1
0
mirror of https://github.com/golang/go synced 2024-11-23 04:20:03 -07:00

cmd/link: mangle function names with ABI on PE

When ABI wrappers are used, we may end up with two functions
having the same name. On ELF we mangle the name with ABI. Do the
same for PE.

TODO: other platforms?

Change-Id: If89f214a6286bc28c062c1aa1bad78dc353a9231
Reviewed-on: https://go-review.googlesource.com/c/go/+/304432
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:
Cherry Zhang 2021-03-24 11:19:19 -04:00
parent 6f62f852ef
commit fd5e0bd385
2 changed files with 40 additions and 33 deletions

View File

@ -694,6 +694,8 @@ func (f *peFile) writeSymbols(ctxt *Link) {
name = "_" + name
}
name = mangleABIName(ldr, s, name)
var peSymType uint16
if ctxt.IsExternal() {
peSymType = IMAGE_SYM_TYPE_NULL

View File

@ -104,39 +104,7 @@ func putelfsym(ctxt *Link, x loader.Sym, typ elf.SymType, curbind elf.SymBind) {
}
sname := ldr.SymExtname(x)
// 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
// name (since this will generated an error from the external
// linker). In the CgoExportStatic case, we want the ABI0 symbol
// to have the primary symbol table entry (since it's going to be
// called from C), so we rename the ABIInternal symbol. In all
// other cases, we rename the ABI0 symbol, since we want
// cross-load-module calls to target ABIInternal.
//
// TODO: generalize this for non-ELF (put the rename code in the
// loader, and store the rename result in SymExtname).
//
// TODO: avoid the ldr.Lookup calls below by instead using an aux
// sym or marker relocation to associate the wrapper with the
// wrapped function.
//
if objabi.Experiment.RegabiWrappers {
if !ldr.IsExternal(x) && ldr.SymType(x) == sym.STEXT {
// First case
if ldr.SymVersion(x) == sym.SymVerABIInternal {
if s2 := ldr.Lookup(sname, sym.SymVerABI0); s2 != 0 && ldr.AttrCgoExportStatic(s2) && ldr.SymType(s2) == sym.STEXT {
sname = sname + ".abiinternal"
}
}
// Second case
if ldr.SymVersion(x) == sym.SymVerABI0 && !ldr.AttrCgoExportStatic(x) {
if s2 := ldr.Lookup(sname, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2) == sym.STEXT {
sname = sname + ".abi0"
}
}
}
}
sname = mangleABIName(ldr, x, sname)
// One pass for each binding: elf.STB_LOCAL, elf.STB_GLOBAL,
// maybe one day elf.STB_WEAK.
@ -863,3 +831,40 @@ func setCarrierSize(typ sym.SymKind, sz int64) {
func isStaticTmp(name string) bool {
return strings.Contains(name, "."+obj.StaticNamePref)
}
// Mangle function name with ABI information.
func mangleABIName(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
// name (since this will generated an error from the external
// linker). In the CgoExportStatic case, we want the ABI0 symbol
// to have the primary symbol table entry (since it's going to be
// called from C), so we rename the ABIInternal symbol. In all
// other cases, we rename the ABI0 symbol, since we want
// cross-load-module calls to target ABIInternal.
//
// TODO: this is currently only used on ELF and PE. Other platforms?
//
// TODO: avoid the ldr.Lookup calls below by instead using an aux
// sym or marker relocation to associate the wrapper with the
// wrapped function.
//
if !objabi.Experiment.RegabiWrappers {
return name
}
if !ldr.IsExternal(x) && ldr.SymType(x) == sym.STEXT {
// First case
if ldr.SymVersion(x) == sym.SymVerABIInternal {
if s2 := ldr.Lookup(name, sym.SymVerABI0); s2 != 0 && ldr.AttrCgoExportStatic(s2) && ldr.SymType(s2) == sym.STEXT {
name = name + ".abiinternal"
}
}
// Second case
if ldr.SymVersion(x) == sym.SymVerABI0 && !ldr.AttrCgoExportStatic(x) {
if s2 := ldr.Lookup(name, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2) == sym.STEXT {
name = name + ".abi0"
}
}
}
return name
}