aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2023-09-29 14:19:17 -0400
committerGopher Robot <gobot@golang.org>2023-10-12 22:37:08 +0000
commitd48639094b3a2275092fff43cd5deb1694f7e9e0 (patch)
tree7b29c3ee230ff259e16ac68a163785bd92ac22bf
parentc8fdffb790f96480cf678b9dcde657ee462b23fa (diff)
downloadgo-d48639094b3a2275092fff43cd5deb1694f7e9e0.tar.gz
go-d48639094b3a2275092fff43cd5deb1694f7e9e0.zip
[release-branch.go1.20] cmd/link: split text sections for arm 32-bit
This CL is a roll-forward (tweaked slightly) of CL 467715, which turned on text section splitting for GOARCH=arm. The intent is to avoid recurrent problems with external linking where there is a disagreement between the Go linker and the external linker over whether a given branch will reach. In the past our approach has been to tweak the reachability calculations slightly to try to work around potential linker problems, but this hasn't proven to be very robust; section splitting seems to offer a better long term fix. Updates #58425. Fixes #63316. Change-Id: I7372d41abce84097906a3d0805b6b9c486f345d6 Reviewed-on: https://go-review.googlesource.com/c/go/+/531795 Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> (cherry picked from commit 1e690409206ff97330b5a91517d453fc5129bab2) Reviewed-on: https://go-review.googlesource.com/c/go/+/532097 Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
-rw-r--r--src/cmd/link/internal/ld/data.go22
-rw-r--r--src/cmd/link/internal/ld/ld_test.go2
2 files changed, 17 insertions, 7 deletions
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 925e554b1d..afba7d3b3c 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -84,6 +84,9 @@ func maxSizeTrampolines(ctxt *Link, ldr *loader.Loader, s loader.Sym, isTramp bo
}
}
+ if ctxt.IsARM() {
+ return n * 20 // Trampolines in ARM range from 3 to 5 instructions.
+ }
if ctxt.IsPPC64() {
return n * 16 // Trampolines in PPC64 are 4 instructions.
}
@@ -2533,15 +2536,22 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64
// Return whether we may need to split text sections.
//
-// On PPC64x whem external linking a text section should not be larger than 2^25 bytes
-// due to the size of call target offset field in the bl instruction. Splitting into
-// smaller text sections smaller than this limit allows the system linker to modify the long
-// calls appropriately. The limit allows for the space needed for tables inserted by the
-// linker.
+// On PPC64x, when external linking, a text section should not be
+// larger than 2^25 bytes due to the size of call target offset field
+// in the 'bl' instruction. Splitting into smaller text sections
+// smaller than this limit allows the system linker to modify the long
+// calls appropriately. The limit allows for the space needed for
+// tables inserted by the linker.
//
// The same applies to Darwin/ARM64, with 2^27 byte threshold.
+//
+// Similarly for ARM, we split sections (at 2^25 bytes) to avoid
+// inconsistencies between the Go linker's reachability calculations
+// (e.g. will direct call from X to Y need a trampoline) and similar
+// machinery in the external linker; see #58425 for more on the
+// history here.
func splitTextSections(ctxt *Link) bool {
- return (ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
+ return (ctxt.IsARM() || ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
}
// On Wasm, we reserve 4096 bytes for zero page, then 8192 bytes for wasm_exec.js
diff --git a/src/cmd/link/internal/ld/ld_test.go b/src/cmd/link/internal/ld/ld_test.go
index 314dab7d7d..4d32dd6a24 100644
--- a/src/cmd/link/internal/ld/ld_test.go
+++ b/src/cmd/link/internal/ld/ld_test.go
@@ -133,7 +133,7 @@ func TestArchiveBuildInvokeWithExec(t *testing.T) {
func TestLargeTextSectionSplitting(t *testing.T) {
switch runtime.GOARCH {
- case "ppc64", "ppc64le":
+ case "ppc64", "ppc64le", "arm":
case "arm64":
if runtime.GOOS == "darwin" {
break