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: register conflict between external linker and duffzero on arm64 #32773
Comments
I think we could change the register used in duffzero, if necessary. Is |
Ok, the ARM64 ABI says
Maybe we should change the register. It seems unlikely that calling duffzero needs a trampoline. I guess you are using shared libraries, where the Go runtime and the Go user code are not in the same module? |
Change https://golang.org/cl/183842 mentions this issue: |
@cherrymui |
The patch in https://golang.org/cl/183842 should fix this. |
@cherrymui |
@xuanjiazhen the patch is in. It will be in Go 1.13 release. |
@cherrymui
If I change back to unmodified go1.12.4, the program will pass normally here. |
@cherrymui |
Handling long jumps should be a separate issue, yes. Thanks. |
I don't think there is a Go 1.12 release with the patch. You can try Go 1.13 beta, which includes the patch. https://golang.org/dl/#go1.13beta1 That said, I realized that CL 183842 is not complete. If there is a linker trampoline involved, R16 and R17 may be clobbered. We moved away from them in Duff's devices, but the register allocator still needs to know they are clobbered. I can send a CL to fix this part. But I still don't know how linker trampoline is involved here. @xuanjiazhen could you share the command you used to build the binary? If you use As @ianlancetaylor said, handling long jumps should be a separate issue. I agree we don't have that support. But it shouldn't be hard, given that we already have the infrastructure for this on ARM32 and PPC64. |
@cherrymui I constructed an example to reproduce the problem over 128M. You can generate a
|
I cannot reproduce the failure with your example. Anyway, I'll send my CL in case it helps. You can apply it on top of Go 1.13 beta1.
You can pass |
Change https://golang.org/cl/184437 mentions this issue: |
On ARM64, (external) linker generated trampoline may clobber R16 and R17. In CL 183842 we change Duff's devices not to use those registers. However, this is not enough. The register allocator also needs to know that these registers may be clobbered in any calls that don't follow the standard Go calling convention. This include Duff's devices and the write barrier. Fixes #32773, second attempt. Change-Id: Ia52a891d9bbb8515c927617dd53aee5af5bd9aa4 Reviewed-on: https://go-review.googlesource.com/c/go/+/184437 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Meng Zhuo <mzh@golangcn.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Meng Zhuo <mzh@golangcn.org>
@gopherbot, please open backport issues. |
Backport issue(s) opened: #46927 (for 1.15), #46928 (for 1.16). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases. |
Change https://golang.org/cl/331029 mentions this issue: |
Change https://golang.org/cl/331030 mentions this issue: |
…standard calls on ARM64 On ARM64, (external) linker generated trampoline may clobber R16 and R17. In CL 183842 we change Duff's devices not to use those registers. However, this is not enough. The register allocator also needs to know that these registers may be clobbered in any calls that don't follow the standard Go calling convention. This include Duff's devices and the write barrier. Fixes #46928. Updates #32773. Change-Id: Ia52a891d9bbb8515c927617dd53aee5af5bd9aa4 Reviewed-on: https://go-review.googlesource.com/c/go/+/184437 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Meng Zhuo <mzh@golangcn.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Meng Zhuo <mzh@golangcn.org> (cherry picked from commit 11b4aee) Reviewed-on: https://go-review.googlesource.com/c/go/+/331029 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com>
…standard calls on ARM64 On ARM64, (external) linker generated trampoline may clobber R16 and R17. In CL 183842 we change Duff's devices not to use those registers. However, this is not enough. The register allocator also needs to know that these registers may be clobbered in any calls that don't follow the standard Go calling convention. This include Duff's devices and the write barrier. Fixes #46927. Updates #32773. Change-Id: Ia52a891d9bbb8515c927617dd53aee5af5bd9aa4 Reviewed-on: https://go-review.googlesource.com/c/go/+/184437 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Meng Zhuo <mzh@golangcn.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Meng Zhuo <mzh@golangcn.org> (cherry picked from commit 11b4aee) Reviewed-on: https://go-review.googlesource.com/c/go/+/331030 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com>
What version of Go are you using (
go version
)?We build our Go app on arm64. In a recent version, we encountered a segment violation error when it run. Through gdb debugging we found that the error originated from the register conflict between external linker and
duffzero
(I guess).The error occurred in a line in the
runtime·duffzero
in duff_arm64.s.It is found by GDB that it is in the __runtime.duffzero_veneer function before entering runtime·duffzero. This function looks like this:
br x16
will jump intoruntime·duffzero
.But at this time the address in x16 is the address of the code segment. Then it went wrong.
cmd/internal/obj/arm64/a.out.go:
REGRT1 = REG_R16 // ARM64 IP0, for external linker, runtime, duffzero and duffcopy
It seems that external linker and duffzero has the same register.
I don't know if I have made it clear. I want to know if this is a bug?
The text was updated successfully, but these errors were encountered: