import (
"os"
-
- "cmd/internal/obj"
)
-var Ctxt *obj.Link
-
var atExitFuncs []func()
func AtExit(f func()) {
--- /dev/null
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+ "cmd/internal/obj"
+)
+
+var Ctxt *obj.Link
+
+// TODO(mdempsky): These should probably be obj.Link methods.
+
+// PkgLinksym returns the linker symbol for name within the given
+// package prefix. For user packages, prefix should be the package
+// path encoded with objabi.PathToPrefix.
+func PkgLinksym(prefix, name string, abi obj.ABI) *obj.LSym {
+ if name == "_" {
+ // TODO(mdempsky): Cleanup callers and Fatalf instead.
+ return linksym(prefix, "_", abi)
+ }
+ return linksym(prefix, prefix+"."+name, abi)
+}
+
+// Linkname returns the linker symbol for the given name as it might
+// appear within a //go:linkname directive.
+func Linkname(name string, abi obj.ABI) *obj.LSym {
+ return linksym("_", name, abi)
+}
+
+// linksym is an internal helper function for implementing the above
+// exported APIs.
+func linksym(pkg, name string, abi obj.ABI) *obj.LSym {
+ return Ctxt.LookupABIInit(name, abi, func(r *obj.LSym) { r.Pkg = pkg })
+}
if fn.Nname != nil {
expect := fn.Linksym()
if fnsym.ABI() == obj.ABI0 {
- expect = fn.Sym().LinksymABI0()
+ expect = fn.LinksymABI(obj.ABI0)
}
if fnsym != expect {
base.Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
func (n *Func) doChildren(do func(Node) bool) bool { return doNodes(n.Body, do) }
func (n *Func) editChildren(edit func(Node) Node) { editNodes(n.Body, edit) }
-func (f *Func) Type() *types.Type { return f.Nname.Type() }
-func (f *Func) Sym() *types.Sym { return f.Nname.Sym() }
-func (f *Func) Linksym() *obj.LSym { return f.Nname.Linksym() }
+func (f *Func) Type() *types.Type { return f.Nname.Type() }
+func (f *Func) Sym() *types.Sym { return f.Nname.Sym() }
+func (f *Func) Linksym() *obj.LSym { return f.Nname.Linksym() }
+func (f *Func) LinksymABI(abi obj.ABI) *obj.LSym { return f.Nname.LinksymABI(abi) }
// An Inline holds fields used for function bodies that can be inlined.
type Inline struct {
n.bits.set2(miniWalkdefShift, x)
}
-func (n *Name) Linksym() *obj.LSym { return n.sym.Linksym() }
+func (n *Name) Linksym() *obj.LSym { return n.sym.Linksym() }
+func (n *Name) LinksymABI(abi obj.ABI) *obj.LSym { return n.sym.LinksymABI(abi) }
func (*Name) CanBeNtype() {}
func (*Name) CanBeAnSSASym() {}
var wrapperABI obj.ABI
needABIWrapper := false
- defABI, hasDefABI := symabiDefs[nam.Sym().LinksymName()]
+ defABI, hasDefABI := symabiDefs[nam.Linksym().Name]
if hasDefABI && defABI == obj.ABI0 {
// Symbol is defined as ABI0. Create an
// Internal -> ABI0 wrapper.
- f.LSym = nam.Sym().LinksymABI0()
+ f.LSym = nam.LinksymABI(obj.ABI0)
needABIWrapper, wrapperABI = true, obj.ABIInternal
} else {
f.LSym = nam.Linksym()
}
} else {
// check for case 2 above
- defABI, hasDefABI := symabiDefs[callee.Sym().LinksymName()]
+ defABI, hasDefABI := symabiDefs[lsym.Name]
if hasDefABI && defABI == obj.ABI0 {
- lsym = callee.Sym().LinksymABI0()
+ lsym = callee.LinksymABI(obj.ABI0)
}
}
return lsym
func WriteFuncSyms() {
sort.Slice(funcsyms, func(i, j int) bool {
- return funcsyms[i].LinksymName() < funcsyms[j].LinksymName()
+ return funcsyms[i].Linksym().Name < funcsyms[j].Linksym().Name
})
for _, s := range funcsyms {
sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym()
// LookupRuntimeFunc looks up Go function name in package runtime. This function
// must follow the internal calling convention.
func LookupRuntimeFunc(name string) *obj.LSym {
- s := ir.Pkgs.Runtime.Lookup(name)
- s.SetFunc(true)
- return s.Linksym()
+ return LookupRuntimeABI(name, obj.ABIInternal)
}
// LookupRuntimeVar looks up a variable (or assembly function) name in package
// runtime. If this is a function, it may have a special calling
// convention.
func LookupRuntimeVar(name string) *obj.LSym {
- return ir.Pkgs.Runtime.Lookup(name).Linksym()
+ return LookupRuntimeABI(name, obj.ABI0)
+}
+
+// LookupRuntimeABI looks up a name in package runtime using the given ABI.
+func LookupRuntimeABI(name string, abi obj.ABI) *obj.LSym {
+ return base.PkgLinksym("runtime", name, abi)
}
return sym != nil && sym.Name == "_"
}
-func (sym *Sym) LinksymName() string {
- if sym.IsBlank() {
- return "_"
- }
- if sym.Linkname != "" {
- return sym.Linkname
- }
- return sym.Pkg.Prefix + "." + sym.Name
-}
-
// Deprecated: This method should not be used directly. Instead, use a
// higher-level abstraction that directly returns the linker symbol
// for a named object. For example, reflectdata.TypeLinksym(t) instead
// of reflectdata.TypeSym(t).Linksym().
func (sym *Sym) Linksym() *obj.LSym {
- if sym == nil {
- return nil
- }
- initPkg := func(r *obj.LSym) {
- if sym.Linkname != "" {
- r.Pkg = "_"
- } else {
- r.Pkg = sym.Pkg.Prefix
- }
- }
+ abi := obj.ABI0
if sym.Func() {
- // This is a function symbol. Mark it as "internal ABI".
- return base.Ctxt.LookupABIInit(sym.LinksymName(), obj.ABIInternal, initPkg)
+ abi = obj.ABIInternal
}
- return base.Ctxt.LookupInit(sym.LinksymName(), initPkg)
+ return sym.LinksymABI(abi)
}
-// LinksymABI0 looks up or creates an ABI0 linker symbol for "sym",
-// in cases where we want to specifically select the ABI0 version of
-// a symbol (typically used only for ABI wrappers).
-func (sym *Sym) LinksymABI0() *obj.LSym {
+// Deprecated: This method should not be used directly. Instead, use a
+// higher-level abstraction that directly returns the linker symbol
+// for a named object. For example, (*ir.Name).LinksymABI(abi) instead
+// of (*ir.Name).Sym().LinksymABI(abi).
+func (sym *Sym) LinksymABI(abi obj.ABI) *obj.LSym {
if sym == nil {
- return nil
+ base.Fatalf("nil symbol")
}
- initPkg := func(r *obj.LSym) {
- if sym.Linkname != "" {
- r.Pkg = "_"
- } else {
- r.Pkg = sym.Pkg.Prefix
- }
+ if sym.Linkname != "" {
+ return base.Linkname(sym.Linkname, abi)
}
- return base.Ctxt.LookupABIInit(sym.LinksymName(), obj.ABI0, initPkg)
+ return base.PkgLinksym(sym.Pkg.Prefix, sym.Name, abi)
}
// Less reports whether symbol a is ordered before symbol b.