src/cmd/compile: clarify //go:linkname documentation

Change-Id: I0407950bfc84082683012944b2051e46dc682ba0
Reviewed-on: https://go-review.googlesource.com/c/go/+/463136
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Alan Donovan 2023-01-23 11:21:27 -05:00
parent 3693fd255f
commit cb3c50db22

View file

@ -247,14 +247,53 @@ at times when it is unsafe for the calling goroutine to be preempted.
//go:linkname localname [importpath.name]
This special directive does not apply to the Go code that follows it.
Instead, 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.
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".
The //go:linkname directive conventionally precedes the var or func
declaration named by ``localname``, though its position does not
change its effect.
This directive determines the object-file symbol used for a Go var or
func declaration, allowing two Go symbols to alias the same
object-file symbol, thereby enabling one package to access a symbol in
another package even when this would violate the usual encapsulation
of unexported declarations, or even type safety.
For that reason, it is only enabled in files that have imported "unsafe".
It may be used in two scenarios. Let's assume that package upper
imports package lower, perhaps indirectly. In the first scenario,
package lower defines a symbol whose object file name belongs to
package upper. Both packages contain a linkname directive: package
lower uses the two-argument form and package upper uses the
one-argument form. In the example below, lower.f is an alias for the
function upper.g:
package upper
import _ "unsafe"
//go:linkname g
func g()
package lower
import _ "unsafe"
//go:linkname f upper.g
func f() { ... }
The linkname directive in package upper suppresses the usual error for
a function that lacks a body. (That check may alternatively be
suppressed by including a .s file, even an empty one, in the package.)
In the second scenario, package upper unilaterally creates an alias
for a symbol in package lower. In the example below, upper.g is an alias
for the function lower.f.
package upper
import _ "unsafe"
//go:linkname g lower.f
func g()
package lower
func f() { ... }
The declaration of lower.f may also have a linkname directive with a
single argument, f. This is optional, but helps alert the reader that
the function is accessed from outside the package.
*/
package main