-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
cmd/compile: -buildmode=c-archive produces code not suitable for use in a shared object on arm64 #62556
Comments
Possibly related: https://sourceware.org/bugzilla/show_bug.cgi?id=28370 ? |
I think this may be because we take the address of a function without going through the GOT, and We probably could bypass the issue by using a local wrapper function. (This comment is interesting
Why it needs to be exported if we're not using -buildmode=shared or -linkshared? In exe, c-archive, or c-shared build modes I think the crosscall2 call are made from cgo-generated code, which is in the same DSO. Maybe SWIG calls can be in another DSO?) |
@nmeum what version of the C linker do you use? Could you show the output of On my machine with |
At the time the "We need to export the symbol crosscall2" comment was written, SWIG (and cgo) worked by writing a shared library. Now that that is no longer can true we can retire the comment. |
I am using |
Thanks. Yeah, that supports my assumption about taking the address of crosscall2 without going through the GOT. I'll work on a fix. |
Thanks @ianlancetaylor . I'll send a CL to remove that comment and un-export crosscall2. |
Change https://go.dev/cl/533535 mentions this issue: |
@nmeum could you try if CL https://go.dev/cl/533535 fixes the issue? With the CL I can see the R_AARCH64_ADR_PREL_PG_HI21 relocation is gone. But I don't have a C toolchain that actually fails without the CL. One way to try it is to use the gotip command
Thanks. |
Yes, with that patch applied fcitx5-bamboo builds again on Alpine Linux aarch64 with binutils 2.41. Thanks! |
@nmeum thanks for confirming! |
@gopherbot please backport this to Go 1.21. This is a regression in Go 1.21 affecting a specific use case without workaround. Thanks. |
Backport issue(s) opened: #63509 (for 1.21). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
Change https://go.dev/cl/534915 mentions this issue: |
Go upstream patch for this issue has been backported. See: golang/go#62556
[ commit 21003a6f78885d934d0b9bb871e360c820a2d813 ] See: * https://go.dev/cl/533535 * golang/go#62556
Currently, set_crosscall2 takes the address of crosscall2 without using the GOT, which, on some architectures, results in a PC-relative relocation (e.g. R_AARCH64_ADR_PREL_PG_HI21 on ARM64) to the crosscall2 symbol. But crosscall2 is dynamically exported, so the C linker thinks it may bind to a symbol from a different DSO. Some C linker may not like a PC-relative relocation to such a symbol. Using a local trampoline to avoid taking the address of a dynamically exported symbol. It may be possible to not dynamically export crosscall2. But this CL is safer for backport. Later we may remove the trampolines after unexport crosscall2, if they are not needed. Fixes golang#62556. Change-Id: Id28457f65ef121d3f87d8189803abc65ed453283 Reviewed-on: https://go-review.googlesource.com/c/go/+/533535 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
…scall2 in code Currently, set_crosscall2 takes the address of crosscall2 without using the GOT, which, on some architectures, results in a PC-relative relocation (e.g. R_AARCH64_ADR_PREL_PG_HI21 on ARM64) to the crosscall2 symbol. But crosscall2 is dynamically exported, so the C linker thinks it may bind to a symbol from a different DSO. Some C linker may not like a PC-relative relocation to such a symbol. Using a local trampoline to avoid taking the address of a dynamically exported symbol. It may be possible to not dynamically export crosscall2. But this CL is safer for backport. Later we may remove the trampolines after unexport crosscall2, if they are not needed. Fixes #63509. Updates #62556. Change-Id: Id28457f65ef121d3f87d8189803abc65ed453283 Reviewed-on: https://go-review.googlesource.com/c/go/+/533535 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com> (cherry picked from commit 872d718) Reviewed-on: https://go-review.googlesource.com/c/go/+/534915 Reviewed-by: David Chase <drchase@google.com>
tl;dr On aarch64, Go 1.21 seems to emit code that is not suitable for use in a C/C++ shared library with
-buildmode=c-archive
on aarch64. I believe this to be a Go 1.21 regression as this was explicitly mentioned as a supported feature in commit d92a360. The root cause seems to be aR_AARCH64_ADR_PREL_PG_HI21
relocation for thecrosscall2
symbol.What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I maintain the Go package for Alpine Linux (which uses musl libc) with the release of Go 1.21.1 we rebuild all of our packaged Go software for the CVE fixes in the standard library. While doing so, we noticed that the package fcitx5-bamboo failed to build from source on aarch64 (on all other architecture it build fine). The error message was:
The package previously compiled fine with Go 1.20.6 on aarch64.
Closer investigation revealed that the fcitx5-bamboo build system does the following:
bamboo-core.a
) usinggo -buildmode=c-archive
.g++ -shared
.Naturally, the error message above is emitted by g++ not by the Go compiler. However, as per a prior discussion on golang-dev and commit d92a360, I believe that files produced by
go build -buildmode=c-archive
are supposed to be suitable for use in a shared library which the file emitted here (bamboo-core.a
) is not. If my assumption is correct, then I believe this to be a regression introduced in Go 1.21, i.e. a bug in the Go compiler. The issue in this regard seems to be aR_AARCH64_ADR_PREL_PG_HI21
relocation emitted forcrosscall2
:I am not familiar enough with aarch64 internals and relocations in general in order to determine why this code requires a
R_AARCH64_ADR_PREL_PG_HI21
relocation and why this relocation is not suitable for use in a shared library.To reproduce this run the following commands on aarch64:
This should print the
R_AARCH64_ADR_PREL_PG_HI21
relocation, or at least it does on Alpine Linux Edge aarch64. Again, I am not sure why this relocation is not suitable for use in a shared library. If you want to re-produce the g++ error message follow the upstream build instructions. Unfortunately, I did not manage to come up with a minimal example yet.Full build log for our failing aarch64 Alpine Linux Edge build: fcitx5-bamboo-go-1.21.1-alpine-linux-edge-aarch64.txt
What did you expect to see?
Successful linking of the c-archive emitted by
go build -buildmode=c-archive
to a shared library withg++ -shared
.What did you see instead?
The g++ error message regarding a
R_AARCH64_ADR_PREL_PG_HI21
relocation.The text was updated successfully, but these errors were encountered: