aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2019-05-31 15:45:06 -0400
committerAustin Clements <austin@google.com>2019-06-06 19:44:10 +0000
commitdde7c770ef44d45b8a9f98bf0f46556f18df2f6e (patch)
tree6eb6394de6c492340ead1a1cb230afdda24a84b8 /src/cmd
parentb402bd4499a59c6f1fac4dc2684390b5d4d1c2eb (diff)
downloadgo-dde7c770ef44d45b8a9f98bf0f46556f18df2f6e.tar.xz
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>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/doc.go8
-rw-r--r--src/cmd/compile/internal/gc/noder.go32
2 files changed, 32 insertions, 8 deletions
diff --git a/src/cmd/compile/doc.go b/src/cmd/compile/doc.go
index 5291a8b0eb..5b437d6804 100644
--- a/src/cmd/compile/doc.go
+++ b/src/cmd/compile/doc.go
@@ -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
preempted.
- //go:linkname localname importpath.name
+ //go:linkname localname [importpath.name]
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
-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".
*/
package main
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index e83ae7c5eb..93d355278e 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -244,10 +244,21 @@ func (p *noder) node() {
xtop = append(xtop, p.decls(p.file.DeclList)...)
for _, n := range p.linknames {
- if imported_unsafe {
- lookup(n.local).Linkname = n.remote
- } else {
+ if !imported_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 "):
f := strings.Fields(text)
- if len(f) != 3 {
- p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname linkname"})
+ if !(2 <= len(f) && len(f) <= 3) {
+ p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname [linkname]"})
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 "):
// This is permitted for general use because Solaris