Go unexported asm functions are global¶
Go compiler and linker helps you to link a go function with an asm implementation. However, the unexported functions are global, which means that if you duplicate some asm files and compile, go may complain to you.
Normal Usage¶
When we say assembly code, we mean the "function body/function implementation" is written in assembly instead of high-level go code. Note that Go assembly is not the machine-specific assembly code; it's the portable assembly code.
In Go, a function can be constituted by two parts, which are separated when using assembly.
- declaration: must in Go format as that's the identifier to call it
- implementation: it could reside inside a
.s
file with the convention
The convention between the declaration and implementations is fragile because you need to consider the data layouts carefully for functions. For more details, refer to the Go Assembly Guide and Go Internal ABI Specification. For now, it's far out of scope.
You can create sum.s
and main.go
and pass compilation, given the following file hierarchy. The ·EmptyFunction
will be linked with go function EmptyFunction
while the EmptyFunction1
is invisible to go code.
// file sum.s, naming is not a part of convention
#include "textflag.h"
TEXT EmptyFunction1(SB), NOSPLIT, $0-0
RET
TEXT ·EmptyFunction(SB), NOSPLIT, $0-0
CALL EmptyFunction1(SB)
RET
// put an empty line to avoid EOF error
Duplication causes issue¶
If you have duplicated the ASM in another package sub
like this:
// file sum.s, naming is not a part of convention
#include "textflag.h"
TEXT EmptyFunction1(SB), NOSPLIT, $0-0
RET
TEXT ·EmptyFunction(SB), NOSPLIT, $0-0
CALL EmptyFunction1(SB)
RET
// put an empty line to avoid EOF error
// main.go
package main
import "example.com/sub"
//go:noinline
func EmptyFunction()
func main() {
EmptyFunction()
sub.EmptyFunction()
}
// sub/sub.go
package sub
//go:noinline
func EmptyFunction()
The symbol EmptyFunction1
is shared globally, so the linker will report error as below when the functions are defined in multiple places.
- linker error:
link: duplicated definition of symbol EmptyFunction1, from example.com/ssa-example/sub and main