mirror of
https://github.com/golang/go
synced 2024-11-23 07:30:05 -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:
parent
6f62f852ef
commit
fd5e0bd385
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user