Skip to content

Commit 4a4212c

Browse files
committed
[dev.regabi] cmd/compile: refactor Linksym creation
Currently there's a lot of logic within package types for creating Linksyms. This CL pulls it out into base, where it can be more easily reused by other compiler code that shouldn't need to depend on package types. Package base probably isn't the best place for this, but it's convenient because it's a package that types already depends on. It's also where the Ctxt object lives, which these functions depend upon. Passes toolstash -cmp w/ -gcflags=all=-abiwrap. Change-Id: I50d8b7e4596955205036969eab24d7dab053b363 Reviewed-on: https://go-review.googlesource.com/c/go/+/284231 Run-TryBot: Matthew Dempsky <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Than McIntosh <[email protected]> Trust: Matthew Dempsky <[email protected]>
1 parent 4f5c603 commit 4a4212c

File tree

10 files changed

+67
-53
lines changed

10 files changed

+67
-53
lines changed

src/cmd/compile/internal/base/base.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@ package base
66

77
import (
88
"os"
9-
10-
"cmd/internal/obj"
119
)
1210

13-
var Ctxt *obj.Link
14-
1511
var atExitFuncs []func()
1612

1713
func AtExit(f func()) {

src/cmd/compile/internal/base/link.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package base
6+
7+
import (
8+
"cmd/internal/obj"
9+
)
10+
11+
var Ctxt *obj.Link
12+
13+
// TODO(mdempsky): These should probably be obj.Link methods.
14+
15+
// PkgLinksym returns the linker symbol for name within the given
16+
// package prefix. For user packages, prefix should be the package
17+
// path encoded with objabi.PathToPrefix.
18+
func PkgLinksym(prefix, name string, abi obj.ABI) *obj.LSym {
19+
if name == "_" {
20+
// TODO(mdempsky): Cleanup callers and Fatalf instead.
21+
return linksym(prefix, "_", abi)
22+
}
23+
return linksym(prefix, prefix+"."+name, abi)
24+
}
25+
26+
// Linkname returns the linker symbol for the given name as it might
27+
// appear within a //go:linkname directive.
28+
func Linkname(name string, abi obj.ABI) *obj.LSym {
29+
return linksym("_", name, abi)
30+
}
31+
32+
// linksym is an internal helper function for implementing the above
33+
// exported APIs.
34+
func linksym(pkg, name string, abi obj.ABI) *obj.LSym {
35+
return Ctxt.LookupABIInit(name, abi, func(r *obj.LSym) { r.Pkg = pkg })
36+
}

src/cmd/compile/internal/dwarfgen/dwarf.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope,
2828
if fn.Nname != nil {
2929
expect := fn.Linksym()
3030
if fnsym.ABI() == obj.ABI0 {
31-
expect = fn.Sym().LinksymABI0()
31+
expect = fn.LinksymABI(obj.ABI0)
3232
}
3333
if fnsym != expect {
3434
base.Fatalf("unexpected fnsym: %v != %v", fnsym, expect)

src/cmd/compile/internal/ir/func.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ func (n *Func) copy() Node { panic(n.no("copy")) }
133133
func (n *Func) doChildren(do func(Node) bool) bool { return doNodes(n.Body, do) }
134134
func (n *Func) editChildren(edit func(Node) Node) { editNodes(n.Body, edit) }
135135

136-
func (f *Func) Type() *types.Type { return f.Nname.Type() }
137-
func (f *Func) Sym() *types.Sym { return f.Nname.Sym() }
138-
func (f *Func) Linksym() *obj.LSym { return f.Nname.Linksym() }
136+
func (f *Func) Type() *types.Type { return f.Nname.Type() }
137+
func (f *Func) Sym() *types.Sym { return f.Nname.Sym() }
138+
func (f *Func) Linksym() *obj.LSym { return f.Nname.Linksym() }
139+
func (f *Func) LinksymABI(abi obj.ABI) *obj.LSym { return f.Nname.LinksymABI(abi) }
139140

140141
// An Inline holds fields used for function bodies that can be inlined.
141142
type Inline struct {

src/cmd/compile/internal/ir/name.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ func (n *Name) SetWalkdef(x uint8) {
226226
n.bits.set2(miniWalkdefShift, x)
227227
}
228228

229-
func (n *Name) Linksym() *obj.LSym { return n.sym.Linksym() }
229+
func (n *Name) Linksym() *obj.LSym { return n.sym.Linksym() }
230+
func (n *Name) LinksymABI(abi obj.ABI) *obj.LSym { return n.sym.LinksymABI(abi) }
230231

231232
func (*Name) CanBeNtype() {}
232233
func (*Name) CanBeAnSSASym() {}

src/cmd/compile/internal/ssagen/abi.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,11 @@ func selectLSym(f *ir.Func, hasBody bool) {
161161

162162
var wrapperABI obj.ABI
163163
needABIWrapper := false
164-
defABI, hasDefABI := symabiDefs[nam.Sym().LinksymName()]
164+
defABI, hasDefABI := symabiDefs[nam.Linksym().Name]
165165
if hasDefABI && defABI == obj.ABI0 {
166166
// Symbol is defined as ABI0. Create an
167167
// Internal -> ABI0 wrapper.
168-
f.LSym = nam.Sym().LinksymABI0()
168+
f.LSym = nam.LinksymABI(obj.ABI0)
169169
needABIWrapper, wrapperABI = true, obj.ABIInternal
170170
} else {
171171
f.LSym = nam.Linksym()

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7403,9 +7403,9 @@ func callTargetLSym(callee *ir.Name, callerLSym *obj.LSym) *obj.LSym {
74037403
}
74047404
} else {
74057405
// check for case 2 above
7406-
defABI, hasDefABI := symabiDefs[callee.Sym().LinksymName()]
7406+
defABI, hasDefABI := symabiDefs[lsym.Name]
74077407
if hasDefABI && defABI == obj.ABI0 {
7408-
lsym = callee.Sym().LinksymABI0()
7408+
lsym = callee.LinksymABI(obj.ABI0)
74097409
}
74107410
}
74117411
return lsym

src/cmd/compile/internal/staticdata/data.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ func NeedFuncSym(s *types.Sym) {
287287

288288
func WriteFuncSyms() {
289289
sort.Slice(funcsyms, func(i, j int) bool {
290-
return funcsyms[i].LinksymName() < funcsyms[j].LinksymName()
290+
return funcsyms[i].Linksym().Name < funcsyms[j].Linksym().Name
291291
})
292292
for _, s := range funcsyms {
293293
sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym()

src/cmd/compile/internal/typecheck/syms.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,17 @@ func InitRuntime() {
8686
// LookupRuntimeFunc looks up Go function name in package runtime. This function
8787
// must follow the internal calling convention.
8888
func LookupRuntimeFunc(name string) *obj.LSym {
89-
s := ir.Pkgs.Runtime.Lookup(name)
90-
s.SetFunc(true)
91-
return s.Linksym()
89+
return LookupRuntimeABI(name, obj.ABIInternal)
9290
}
9391

9492
// LookupRuntimeVar looks up a variable (or assembly function) name in package
9593
// runtime. If this is a function, it may have a special calling
9694
// convention.
9795
func LookupRuntimeVar(name string) *obj.LSym {
98-
return ir.Pkgs.Runtime.Lookup(name).Linksym()
96+
return LookupRuntimeABI(name, obj.ABI0)
97+
}
98+
99+
// LookupRuntimeABI looks up a name in package runtime using the given ABI.
100+
func LookupRuntimeABI(name string, abi obj.ABI) *obj.LSym {
101+
return base.PkgLinksym("runtime", name, abi)
99102
}

src/cmd/compile/internal/types/sym.go

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -64,53 +64,30 @@ func (sym *Sym) IsBlank() bool {
6464
return sym != nil && sym.Name == "_"
6565
}
6666

67-
func (sym *Sym) LinksymName() string {
68-
if sym.IsBlank() {
69-
return "_"
70-
}
71-
if sym.Linkname != "" {
72-
return sym.Linkname
73-
}
74-
return sym.Pkg.Prefix + "." + sym.Name
75-
}
76-
7767
// Deprecated: This method should not be used directly. Instead, use a
7868
// higher-level abstraction that directly returns the linker symbol
7969
// for a named object. For example, reflectdata.TypeLinksym(t) instead
8070
// of reflectdata.TypeSym(t).Linksym().
8171
func (sym *Sym) Linksym() *obj.LSym {
82-
if sym == nil {
83-
return nil
84-
}
85-
initPkg := func(r *obj.LSym) {
86-
if sym.Linkname != "" {
87-
r.Pkg = "_"
88-
} else {
89-
r.Pkg = sym.Pkg.Prefix
90-
}
91-
}
72+
abi := obj.ABI0
9273
if sym.Func() {
93-
// This is a function symbol. Mark it as "internal ABI".
94-
return base.Ctxt.LookupABIInit(sym.LinksymName(), obj.ABIInternal, initPkg)
74+
abi = obj.ABIInternal
9575
}
96-
return base.Ctxt.LookupInit(sym.LinksymName(), initPkg)
76+
return sym.LinksymABI(abi)
9777
}
9878

99-
// LinksymABI0 looks up or creates an ABI0 linker symbol for "sym",
100-
// in cases where we want to specifically select the ABI0 version of
101-
// a symbol (typically used only for ABI wrappers).
102-
func (sym *Sym) LinksymABI0() *obj.LSym {
79+
// Deprecated: This method should not be used directly. Instead, use a
80+
// higher-level abstraction that directly returns the linker symbol
81+
// for a named object. For example, (*ir.Name).LinksymABI(abi) instead
82+
// of (*ir.Name).Sym().LinksymABI(abi).
83+
func (sym *Sym) LinksymABI(abi obj.ABI) *obj.LSym {
10384
if sym == nil {
104-
return nil
85+
base.Fatalf("nil symbol")
10586
}
106-
initPkg := func(r *obj.LSym) {
107-
if sym.Linkname != "" {
108-
r.Pkg = "_"
109-
} else {
110-
r.Pkg = sym.Pkg.Prefix
111-
}
87+
if sym.Linkname != "" {
88+
return base.Linkname(sym.Linkname, abi)
11289
}
113-
return base.Ctxt.LookupABIInit(sym.LinksymName(), obj.ABI0, initPkg)
90+
return base.PkgLinksym(sym.Pkg.Prefix, sym.Name, abi)
11491
}
11592

11693
// Less reports whether symbol a is ordered before symbol b.

0 commit comments

Comments
 (0)