The use of linkname in go

  • 2020-07-21 08:27:59
  • OfStack

In the source code of go language, you can find a lot of code, only function signature, but not the function body, such as:


// src/os/proc.go 68 line 
func runtime_beforeExit() // implemented in runtime

Here we only see the signature of the function, but not the body of the function. After searching 1 globally, we find that the body of the function is defined in src/runtime/proc.go In the


// os_beforeExit is called from os.Exit(0).
//go:linkname os_beforeExit os.runtime_beforeExit
func os_beforeExit() {
  if raceenabled {
    racefini()
  }
}

It concatenates the function signature and the function body at 1 through go:linkname. So can we do that in our code? If we can use this in library functions, can we use this in our own code structure? The following USES are implemented experimentally, step by step

Create a project directory

$mkdir demo && cd demo

go mod initializes the project directory

$go mod init demo

Create the function signature pkg and the function body pkg


$mkdir hello
$mkdir link

Write test code


$cd hello
//  Function signatures 
$vim hello.go
package hello
import (
  _ "demo/link"
)
func Hello()
//  The body of the function 
$vim link.go
package link
import _ "unsafe"
//go:linkname helloWorld demo/hello.Hello
func helloWorld() {
  println("hello world!")
}

Execute the code


$cd demo
vim demo.go
package main
import (
  "demo/hello"
)
func main() {
  hello.Hello()
}

Compile operation


go run demo.go
# demo/hello
hello/hello.go:7:6: missing function body

Add aa.s to the hello folder to enable compilation


$cd hello && touch aa.s
$go run demo.go
hello world!

conclusion