mirror of
https://github.com/golang/go
synced 2024-11-24 05:50:13 -07:00
cmd/compile: simplify func value symbol generation
Currently, in most cases the compiler generates a func value symbol when it is referenced, except when building a shared object it generates the func value symbol when the function is declared. The comment says this was necessary because we cannot deduplicate DUPOK symbols across DSO boundaries. But the dynamic linker is just fine to resolve symbols with the same name across DSO boundaries. Another problem may be that the address of the PLT stub may be used. When such a func value is deferred, when the runtime needs to scan its arguments, it cannot look up the PC to find the function and therefore cannot find its stack map. This is not a problem now as deferred functions always have no arguments. Remove the special case for shared linkage. Change-Id: Id7df0b0ada6d3d7f85741a9ab09581975509516c Reviewed-on: https://go-review.googlesource.com/c/go/+/396534 Trust: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
b76f8df133
commit
b1e83c0513
@ -14,7 +14,6 @@ import (
|
||||
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/ir"
|
||||
"cmd/compile/internal/staticdata"
|
||||
"cmd/compile/internal/typecheck"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/obj"
|
||||
@ -243,17 +242,6 @@ func InitLSym(f *ir.Func, hasBody bool) {
|
||||
if f.Pragma&ir.Systemstack != 0 {
|
||||
f.LSym.Set(obj.AttrCFunc, true)
|
||||
}
|
||||
if f.ABI == obj.ABIInternal || !buildcfg.Experiment.RegabiWrappers {
|
||||
// Function values can only point to
|
||||
// ABIInternal entry points. This will create
|
||||
// the funcsym for either the defining
|
||||
// function or its wrapper as appropriate.
|
||||
//
|
||||
// If we're not using ABI wrappers, we only
|
||||
// InitLSym for the defining ABI of a function,
|
||||
// so we make the funcsym when we see that.
|
||||
staticdata.NeedFuncSym(f)
|
||||
}
|
||||
}
|
||||
if hasBody {
|
||||
setupTextLSym(f, 0)
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"internal/buildcfg"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -236,15 +235,9 @@ func FuncLinksym(n *ir.Name) *obj.LSym {
|
||||
// except for the types package, which is protected separately.
|
||||
// Reusing funcsymsmu to also cover this package lookup
|
||||
// avoids a general, broader, expensive package lookup mutex.
|
||||
// Note NeedFuncSym also does package look-up of func sym names,
|
||||
// but that it is only called serially, from the front end.
|
||||
funcsymsmu.Lock()
|
||||
sf, existed := s.Pkg.LookupOK(ir.FuncSymName(s))
|
||||
// Don't export s·f when compiling for dynamic linking.
|
||||
// When dynamically linking, the necessary function
|
||||
// symbols will be created explicitly with NeedFuncSym.
|
||||
// See the NeedFuncSym comment for details.
|
||||
if !base.Ctxt.Flag_dynlink && !existed {
|
||||
if !existed {
|
||||
funcsyms = append(funcsyms, n)
|
||||
}
|
||||
funcsymsmu.Unlock()
|
||||
@ -259,48 +252,6 @@ func GlobalLinksym(n *ir.Name) *obj.LSym {
|
||||
return n.Linksym()
|
||||
}
|
||||
|
||||
// NeedFuncSym ensures that fn·f is exported, if needed.
|
||||
// It is only used with -dynlink.
|
||||
// When not compiling for dynamic linking,
|
||||
// the funcsyms are created as needed by
|
||||
// the packages that use them.
|
||||
// Normally we emit the fn·f stubs as DUPOK syms,
|
||||
// but DUPOK doesn't work across shared library boundaries.
|
||||
// So instead, when dynamic linking, we only create
|
||||
// the fn·f stubs in fn's package.
|
||||
func NeedFuncSym(fn *ir.Func) {
|
||||
if base.Ctxt.InParallel {
|
||||
// The append below probably just needs to lock
|
||||
// funcsymsmu, like in FuncSym.
|
||||
base.Fatalf("NeedFuncSym must be called in serial")
|
||||
}
|
||||
if fn.ABI != obj.ABIInternal && buildcfg.Experiment.RegabiWrappers {
|
||||
// Function values must always reference ABIInternal
|
||||
// entry points, so it doesn't make sense to create a
|
||||
// funcsym for other ABIs.
|
||||
//
|
||||
// (If we're not using ABI wrappers, it doesn't matter.)
|
||||
base.Fatalf("expected ABIInternal: %v has %v", fn.Nname, fn.ABI)
|
||||
}
|
||||
if ir.IsBlank(fn.Nname) {
|
||||
// Blank functions aren't unique, so we can't make a
|
||||
// funcsym for them.
|
||||
base.Fatalf("NeedFuncSym called for _")
|
||||
}
|
||||
if !base.Ctxt.Flag_dynlink {
|
||||
return
|
||||
}
|
||||
s := fn.Nname.Sym()
|
||||
if base.Flag.CompilingRuntime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") ||
|
||||
(base.Ctxt.Pkgpath == "internal/abi" && (s.Name == "FuncPCABI0" || s.Name == "FuncPCABIInternal")) {
|
||||
// runtime.getg(), getclosureptr(), getcallerpc(), getcallersp(),
|
||||
// and internal/abi.FuncPCABIxxx() are not real functions and so
|
||||
// do not get funcsyms.
|
||||
return
|
||||
}
|
||||
funcsyms = append(funcsyms, fn.Nname)
|
||||
}
|
||||
|
||||
func WriteFuncSyms() {
|
||||
sort.Slice(funcsyms, func(i, j int) bool {
|
||||
return funcsyms[i].Linksym().Name < funcsyms[j].Linksym().Name
|
||||
|
Loading…
Reference in New Issue
Block a user