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) }
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
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
}
}
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
}
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.
}
// 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
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
}