go:linkname for Gophers
— Golang, Compiler, Directives — 1 min read
Go has a list of compiler directives.
These directives specify how a compiler should process its output.
They can also be used for non standard behaviors.
These directives are added as comments above either methods or variables.
They are similar to either the build or embed tags.
Note it is important to not leave any space between the go
and the forward slashes, otherwise they won't be picked up by the compiler.
//go:build//go:embed//go:linkname
Why?
go:linkname
can be used to access or override unexported methods.
In general, it should be avoided since there is no guarantee that the behavior won't change in future Go versions.
This is still a cool feature of Go, so let's explore it further.
How?
For this example, we'll be accessing the unexported method open
in a separate package:
package door
import ( "fmt")
func open() { fmt.Printf("Opening the door!")}
Add an empty exportable method in your package. Remember to import the package containing your unexported method, otherwise it will fail to compile:
package open
import _ "example1/door"
func Open()
Next, add an empty assembly file i.s
in the open
package. If this is not added, you'll get a missing function body
error.
Finally add the go:linkname
directive to the unexported method. Remember to import the unsafe
package as well:
package door
import ( "fmt" _ "unsafe")
//go:linkname open example1/open.Openfunc open() { fmt.Printf("Opening the door!")}
Checkout the playground
References
- http://siadat.github.io/blog/post/golinkname
- https://www.pixelstech.net/article/1649596852-The-magic-of-go%3Alinkname
- https://lnquy.com/blog/go-linkname/
The road to success is always under construction