mirror of
https://github.com/golang/go.git
synced 2025-05-17 21:34:36 +00:00
cmd/compile: make the second argument to go:linkname optional
The //go:linkname directive can be used to make a symbol accessible to another package (when it wouldn't normally be). Sometimes you want to do this without actually changing the symbol's object file symbol name; for example, in gccgo this makes unexported symbols non-static, and in gc this provides ABI0 wrappers for Go symbols so they can be called from assembly in other packages. Currently, this results in stutter like //go:linkname entersyscall runtime.entersyscall This CL makes the second argument to go:linkname optional for the case where the intent is simply to expose the symbol rather than to rename it in the object file. Updates #31230. Change-Id: Id06d9c4b2ec3d8e27f9b8a0d65212ab8048d734f Reviewed-on: https://go-review.googlesource.com/c/go/+/179861 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
b402bd4499
commit
dde7c770ef
@ -216,11 +216,15 @@ not include a stack overflow check. This is most commonly used by low-level
|
|||||||
runtime sources invoked at times when it is unsafe for the calling goroutine to be
|
runtime sources invoked at times when it is unsafe for the calling goroutine to be
|
||||||
preempted.
|
preempted.
|
||||||
|
|
||||||
//go:linkname localname importpath.name
|
//go:linkname localname [importpath.name]
|
||||||
|
|
||||||
The //go:linkname directive instructs the compiler to use ``importpath.name'' as the
|
The //go:linkname directive instructs the compiler to use ``importpath.name'' as the
|
||||||
object file symbol name for the variable or function declared as ``localname'' in the
|
object file symbol name for the variable or function declared as ``localname'' in the
|
||||||
source code. Because this directive can subvert the type system and package
|
source code.
|
||||||
|
If the ``importpath.name'' argument is omitted, the directive uses the
|
||||||
|
symbol's default object file symbol name and only has the effect of making
|
||||||
|
the symbol accessible to other packages.
|
||||||
|
Because this directive can subvert the type system and package
|
||||||
modularity, it is only enabled in files that have imported "unsafe".
|
modularity, it is only enabled in files that have imported "unsafe".
|
||||||
*/
|
*/
|
||||||
package main
|
package main
|
||||||
|
@ -244,10 +244,21 @@ func (p *noder) node() {
|
|||||||
xtop = append(xtop, p.decls(p.file.DeclList)...)
|
xtop = append(xtop, p.decls(p.file.DeclList)...)
|
||||||
|
|
||||||
for _, n := range p.linknames {
|
for _, n := range p.linknames {
|
||||||
if imported_unsafe {
|
if !imported_unsafe {
|
||||||
lookup(n.local).Linkname = n.remote
|
|
||||||
} else {
|
|
||||||
p.yyerrorpos(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
|
p.yyerrorpos(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s := lookup(n.local)
|
||||||
|
if n.remote != "" {
|
||||||
|
s.Linkname = n.remote
|
||||||
|
} else {
|
||||||
|
// Use the default object symbol name if the
|
||||||
|
// user didn't provide one.
|
||||||
|
if myimportpath == "" {
|
||||||
|
p.yyerrorpos(n.pos, "//go:linkname requires linkname argument or -p compiler flag")
|
||||||
|
} else {
|
||||||
|
s.Linkname = objabi.PathToPrefix(myimportpath) + "." + n.local
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1476,11 +1487,20 @@ func (p *noder) pragma(pos syntax.Pos, text string) syntax.Pragma {
|
|||||||
|
|
||||||
case strings.HasPrefix(text, "go:linkname "):
|
case strings.HasPrefix(text, "go:linkname "):
|
||||||
f := strings.Fields(text)
|
f := strings.Fields(text)
|
||||||
if len(f) != 3 {
|
if !(2 <= len(f) && len(f) <= 3) {
|
||||||
p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname linkname"})
|
p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname [linkname]"})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
p.linknames = append(p.linknames, linkname{pos, f[1], f[2]})
|
// The second argument is optional. If omitted, we use
|
||||||
|
// the default object symbol name for this and
|
||||||
|
// linkname only serves to mark this symbol as
|
||||||
|
// something that may be referenced via the object
|
||||||
|
// symbol name from another package.
|
||||||
|
var target string
|
||||||
|
if len(f) == 3 {
|
||||||
|
target = f[2]
|
||||||
|
}
|
||||||
|
p.linknames = append(p.linknames, linkname{pos, f[1], target})
|
||||||
|
|
||||||
case strings.HasPrefix(text, "go:cgo_import_dynamic "):
|
case strings.HasPrefix(text, "go:cgo_import_dynamic "):
|
||||||
// This is permitted for general use because Solaris
|
// This is permitted for general use because Solaris
|
||||||
|
Loading…
x
Reference in New Issue
Block a user