Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go:linkname must refer to declared function or variable #51706

Closed
littlejiancc opened this issue Mar 16, 2022 · 17 comments
Closed

go:linkname must refer to declared function or variable #51706

littlejiancc opened this issue Mar 16, 2022 · 17 comments

Comments

@littlejiancc
Copy link

littlejiancc commented Mar 16, 2022

What version of Go are you using (go version)?

$ go version
go version go1.18 darwin/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/wxj/Library/Caches/go-build"
GOENV="/Users/wxj/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/wxj/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/wxj/go"
GOPRIVATE=""
GOPROXY="https://goproxy.io"
GOROOT="/Users/wxj/sdk/go1.18"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/wxj/sdk/go1.18/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.18"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/wxj/go/src/demo/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/85/j24r836d5ygfhjgsn4j5zr0m0000gn/T/go-build178809849=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

$ tree
.
├── 1.s
├── go.mod
├── go.sum
├── inner
│   └── inner.go
└── main.go
$ cat inner.go
package inner

type name struct {
	name string
}

func hello() {
	n := name{
		name: "jack",
	}
	println("hello", n.name)
}

$ cat main.go
package main

import (
	`fmt`

	_ "demo/inner"
	_ "unsafe"
)

//go:linkname hello demo/inner.hello
func hello()

//go:linkname runtimeG runtime.g
type runtimeG struct {
}

func main() {
	hello()
	r := runtimeG{}
	fmt.Println(r)
}

go run main.go

What did you expect to see?

hello jack
{}

What did you see instead?

# command-line-arguments
./main.go:13:3: //go:linkname must refer to declared function or variable

I think runtimeG is declared in main.go, And it works well in version 1.17.8 and 1.16.4

Maybe I'm using it incorrectly, hope it clears my mind, thanks very much!

@seankhliao
Copy link
Member

reaching into the runtime isn't supported

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@JasonRadcliffe
Copy link

I had the same issue running go 1.18 today - the solution on this thread solved it for me. I don't think the variable name runtime has anything to do with it. This does seem like it might be a bug of some kind given I fresh installed go on a fresh image and had source code version mismatching going on.

https://stackoverflow.com/questions/71507321/go-1-18-build-error-on-mac-unix-syscall-darwin-1-13-go253-golinkname-mus

et304383 added a commit to et304383/m1-terraform-provider-helper that referenced this issue Apr 4, 2022
bom-d-van added a commit to go-graphite/go-carbon that referenced this issue Apr 19, 2022
Build is failing on osx due to the following error:

```
vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go:29:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go:27:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go:40:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:28:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:43:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:59:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:75:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:90:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:105:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:121:3: //go:linkname must refer to declared function or variable
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go:121:3: too many errors
```

Upgrading sys package resolves the issue.
Discussions: golang/go#51706
sergeydobrodey added a commit to sergeydobrodey/go-oas3 that referenced this issue May 6, 2022
mikekonan pushed a commit to mikekonan/go-oas3 that referenced this issue May 12, 2022
ink-splatters added a commit to ink-splatters/got that referenced this issue May 25, 2022
golang/go#51706

by updating golang.org/x/sys to the latest version
ink-splatters added a commit to ink-splatters/got that referenced this issue Aug 1, 2022
golang/go#51706

by updating golang.org/x/sys to the latest version
@shearn89
Copy link

To summarise the fix in case of linkrot, try:

go get -u golang.org/x/sys

to update sys and hopefully fix the issue.

@chengjoey
Copy link

Even after upgrading the golang.org/x/sys package, the problem is still not solved, why close this issue
@seankhliao

@mvdan
Copy link
Member

mvdan commented Sep 27, 2022

We appear to be conflating two issues here.

(1) People who try to use //go:linkname themselves to directly access unexported APIs in the standard library. If you do that, it may work, but it is not supported nor guaranteed to keep working in future Go versions. It is not covered by the Go backwards compatibility guarantee.

This is what the original author mentioned, and Sean is right to have closed the issue - you are free to use the linker directive, but you're on your own when it breaks. In fact, I even struggle to find any official documentation that explains how to use //go:linkname - I'm fairly sure it wasn't really intended for use outside of the standard library and some tightly-coupled packages like x/sys/unix.

(2) People who get build errors with a particular versions of Go and x/sys. Like previous commenters have mentioned, this is most likely because either of your Go or x/sys versions are too old.

As you can see on https://build.golang.org/, the "x" modules like x/sys are continuously tested on Go master as well as the two latest stable Go versions (1.18.x and 1.19.x at the time of writing). If your x/sys version is recent, your Go version should be recent too.

Similarly, if your Go version is recent, you should make sure your x/sys version is recent as well. I personally do this by running go get -t -u ./... on my projects every now and then, such as when doing a new major release or when upgrading Go to a new major version.

@littlejiancc
Copy link
Author

hi @mvdan

Whether it's a //go:linkname struct to runtime package or a custom package, this works in go1.17, but not in go1.18 and go1.19, I want to know the reason but I didn't find the relevant documentation.

@chengjoey
Copy link

If you mean your original example, again, that was always undocumented behavior and never guaranteed to work.

project:

├── 1.s
├── inner
│   └── inner.go
└── main.go

inner.go:

package inner

import (
	"fmt"
)

var a int = 100

type student struct {
	age int
}

func hello() {
	fmt.Println("hello")
}

main.go:

package main

import (
	"fmt"
	_ "unsafe"

	_ "demo/inner"
)

//go:linkname A demo/inner.a
var A int

//go:linkname Student demo/inner.student
type Student struct{}

//go:linkname Hello demo/inner.hello
func Hello()

func main() {
	Hello()
	fmt.Println(A)
	fmt.Println(Student{})
}

run go run main.go

result in 1.17 version:

hello
100
{}

result in 1.18 and later:

# command-line-arguments
./main.go:13:3: //go:linkname must refer to declared function or variable

I didn't import the x/sys package or the runtime package, I think should get the same result in different versions

@chengjoey
Copy link

chengjoey commented Sep 27, 2022

I found that in version 1.18 and later, functions and variables still work, the linkname for struct is not supported, but I didn't find instructions in the official documentation

@mvdan
Copy link
Member

mvdan commented Sep 27, 2022

See https://go-review.googlesource.com/c/go/+/333109/. Once again, go:linkname is not documented nor supported as far as I can tell.

@chengjoey
Copy link

See https://go-review.googlesource.com/c/go/+/333109/. Once again, go:linkname is not documented nor supported as far as I can tell.

ok, since there is not documented nor supported then I have nothing to say

@chengjoey
Copy link

chengjoey commented Sep 27, 2022

func (p *noder) processPragmas() {
for _, l := range p.linknames {
if !p.importedUnsafe {
p.errorAt(l.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
continue
}
n := ir.AsNode(typecheck.Lookup(l.local).Def)
if n == nil || n.Op() != ir.ONAME {
// TODO(mdempsky): Change to p.errorAt before Go 1.17 release.
// base.WarnfAt(p.makeXPos(l.pos), "//go:linkname must refer to declared function or variable (will be an error in Go 1.17)")
continue
}
if n.Sym().Linkname != "" {
p.errorAt(l.pos, "duplicate //go:linkname for %s", l.local)
continue
}
n.Sym().Linkname = l.remote
}
typecheck.Target.CgoPragmas = append(typecheck.Target.CgoPragmas, p.pragcgobuf...)
}

go/test/linkname2.go

Lines 16 to 30 in 15da892

//go:linkname x ok
// ERROR "//go:linkname requires linkname argument or -p compiler flag"
// BAD: want error "//go:linkname must refer to declared function or variable"
// BAD: want error "//go:linkname must refer to declared function or variable"
// ERROR "duplicate //go:linkname for x"
// The two BAD lines are just waiting for #42938 before we can
// re-enable the errors.
//line linkname2.go:18
//go:linkname y
//go:linkname nonexist nonexist
//go:linkname t notvarfunc
//go:linkname x duplicate

i think may be the error go:linkname must refer to declared function or variable is re-enabled in 1.18 and only support Func, Var.

in 1.17, type Struct does not take effect,Ignore the error directly

@mvdan
Copy link
Member

mvdan commented Sep 27, 2022

@chengjoey see #55889 (comment).

@mdempsky
Copy link
Contributor

You can't use //go:linkname on a type declaration.

kangaechu pushed a commit to crowdworks/slacts that referenced this issue Oct 17, 2022
I got an error:
../../../../pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:28:3: //go:linkname must refer to declared function or variable

golang/go#51706 (comment)

I updated golang.org/x/sys according to the above instructions.
kangaechu pushed a commit to crowdworks/slacts that referenced this issue Oct 17, 2022
I got an error:
../../../../pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:28:3: //go:linkname must refer to declared function or variable

golang/go#51706 (comment)

I updated golang.org/x/sys according to the above instructions.
kangaechu pushed a commit to crowdworks/slacts that referenced this issue Oct 17, 2022
I got an error:
../../../../pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:28:3: //go:linkname must refer to declared function or variable

golang/go#51706 (comment)

I updated golang.org/x/sys according to the above instructions.
@fzhange
Copy link

fzhange commented Oct 18, 2022

To summarise the fix in case of linkrot, try:

go get -u golang.org/x/sys

to update sys and hopefully fix the issue.

it's powerful

@JohnAllen
Copy link

Sounds like this was definitely a bug report since upgrading the package fixed it.

@chengjoey
Copy link

You can't use //go:linkname on a type declaration.

I agree with your point of view, just looks a little confused that 1.18 and later versions will report an error,but 1.17 don't report an error

anguslees added a commit to anguslees/go-jsonnet that referenced this issue Oct 26, 2022
Update `golang.org/x/sys` package to address golang/go#51706

Update bazel `rules_go` to address bazel-contrib/rules_go#3199
sparkprime pushed a commit to google/go-jsonnet that referenced this issue Oct 26, 2022
Update `golang.org/x/sys` package to address golang/go#51706

Update bazel `rules_go` to address bazel-contrib/rules_go#3199
R-cen added a commit to SafetyCulture/clair-scanner that referenced this issue Jun 13, 2023
@golang golang locked and limited conversation to collaborators Oct 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants