1
0
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:
Cherry Mui 2022-03-29 12:59:12 -04:00
parent b76f8df133
commit b1e83c0513
2 changed files with 1 additions and 62 deletions

View File

@ -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)

View File

@ -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