mirror of
https://github.com/golang/go
synced 2024-11-26 11:58:07 -07:00
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 <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
879db69ce2
commit
d7473fd907
@ -503,10 +503,8 @@ func (ctxt *Link) loadlib() {
|
|||||||
default:
|
default:
|
||||||
log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
|
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.
|
// 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
|
flags |= loader.FlagUseABIAlias
|
||||||
}
|
}
|
||||||
elfsetstring1 := func(str string, off int) { elfsetstring(ctxt, 0, str, off) }
|
elfsetstring1 := func(str string, off int) { elfsetstring(ctxt, 0, str, off) }
|
||||||
@ -2088,25 +2086,6 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
|||||||
return
|
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 {
|
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
|
||||||
@ -2119,14 +2098,13 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
|||||||
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 buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
|
} 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") {
|
if strings.HasSuffix(elfsym.Name, ".abiinternal") {
|
||||||
ver = sym.SymVerABIInternal
|
ver = sym.SymVerABIInternal
|
||||||
symname = strings.TrimSuffix(elfsym.Name, ".abiinternal")
|
symname = strings.TrimSuffix(elfsym.Name, ".abiinternal")
|
||||||
} else if strings.HasSuffix(elfsym.Name, ".abi0") {
|
} else if strings.HasSuffix(elfsym.Name, ".abi0") {
|
||||||
ver = 0
|
ver = 0
|
||||||
symname = strings.TrimSuffix(elfsym.Name, ".abi0")
|
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)
|
l.SetSymExtname(s, elfsym.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For function symbols, we don't know what ABI is
|
// For function symbols, if ABI wrappers are not used, we don't
|
||||||
// available, so alias it under both ABIs.
|
// 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 {
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
alias := ctxt.loader.LookupOrCreateSym(symname, sym.SymVerABIInternal)
|
alias := ctxt.loader.LookupOrCreateSym(symname, sym.SymVerABIInternal)
|
||||||
if l.SymType(alias) != 0 {
|
if l.SymType(alias) != 0 {
|
||||||
continue
|
continue
|
||||||
|
@ -1047,7 +1047,7 @@ func machosymtab(ctxt *Link) {
|
|||||||
// replace "·" as ".", because DTrace cannot handle it.
|
// replace "·" as ".", because DTrace cannot handle it.
|
||||||
name := strings.Replace(ldr.SymExtname(s), "·", ".", -1)
|
name := strings.Replace(ldr.SymExtname(s), "·", ".", -1)
|
||||||
|
|
||||||
name = mangleABIName(ldr, s, name)
|
name = mangleABIName(ctxt, ldr, s, name)
|
||||||
symstr.Addstring(name)
|
symstr.Addstring(name)
|
||||||
|
|
||||||
if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
|
if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
|
||||||
|
@ -727,7 +727,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
|
|||||||
name = "_" + name
|
name = "_" + name
|
||||||
}
|
}
|
||||||
|
|
||||||
name = mangleABIName(ldr, s, name)
|
name = mangleABIName(ctxt, ldr, s, name)
|
||||||
|
|
||||||
var peSymType uint16
|
var peSymType uint16
|
||||||
if ctxt.IsExternal() {
|
if ctxt.IsExternal() {
|
||||||
|
@ -105,7 +105,7 @@ func putelfsym(ctxt *Link, x loader.Sym, typ elf.SymType, curbind elf.SymBind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sname := ldr.SymExtname(x)
|
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,
|
// One pass for each binding: elf.STB_LOCAL, elf.STB_GLOBAL,
|
||||||
// maybe one day elf.STB_WEAK.
|
// maybe one day elf.STB_WEAK.
|
||||||
@ -834,9 +834,9 @@ func isStaticTmp(name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mangle function name with ABI information.
|
// 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
|
// 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
|
// name (since this will generated an error from the external
|
||||||
// linker). If we have wrappers, keep the ABIInternal name
|
// linker). If we have wrappers, keep the ABIInternal name
|
||||||
// unmangled since we want cross-load-module calls to target
|
// 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))
|
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
|
return name
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user