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