Go’s Wall of Shame and the Forbidden 'linkname' directive

By nevillecain on May 10, 2025

While reading through some of the Go source code, I noticed quite a few comments with this little line:

// Notable members of the hall of shame include:

You can grep it yourself:

grep "members of the hall of shame" -rni *

It turns out that some Go maintainers are keeping an informal callout list: a public list of packages that are, in their view, misusing certain internal features. Most of it relates to the infamous //go:linkname directive.

Before diving into a concrete example, let’s quickly explain what a directive is in Go.

🔧 What’s a Directive in Go?

It’s a comment that controls the behavior of the Go toolchain — the compiler, linker, or generators. You’ve probably used one without even thinking much about it, for example:

//go:generate go run gen.go

This works with the go generate command, which looks for //go:generate lines and runs them as shell commands.

Another (less known) directive is //go:linkname. It’s the one responsible for this mysterious "hall of shame" comment trail.

🔗 What is //go:linkname?

The linkname directive lets you link a local Go function to a symbol (even unexported) in another package, including standard library ones.

Let’s look at a real example. In the time package, there’s a private function:

//go:linkname nextStdChunk 
func nextStdChunk(layout string) (prefix string, std int, suffix string) {
    ...
}

This function is not exported, meaning you can’t just write time.nextStdChunk in your own code.

Still, with linkname, you can basically tell the linker:

“Hey, I know what I’m doing. Trust me.”

Here’s how you can actually call that internal function:

package main

import (
    "fmt"
    _ "unsafe"
)

//go:linkname nextStdChunk time.nextStdChunk
func nextStdChunk(layout string) (prefix string, std int, suffix string)

func main() {
    prefix, std, suffix := nextStdChunk("2006-01-02 15:04:05")
    fmt.Println("Prefix:", prefix)
    fmt.Println("Std:", std)
    fmt.Println("Suffix:", suffix)
}

And when you run it:

go run main.go

You’ll get output like:

Prefix: 
Std: 275
Suffix: -01-02 15:04:05

We don’t really care about the output but the point is: you just called a private function from the standard library.

🧱 Why This Is Controversial

Go’s core team uses //go:linkname internally for legit reasons, e.g. to reuse internal helpers across packages without exposing them publicly. But they really don’t want external users doing the same thing.

Still, people do it anyway.

Interestingly, from my testing, trying to use linkname to access private functions in your own packages (non-stdlib) doesn’t work as easily, it looks like Go adds protection layers there.

Go source-code directive linkname
About the Author

Software developer specialized in backend systems.