b7c185ab01
Resolves: rhbz#1955035 Resolves: rhbz#1957961
76 lines
3.3 KiB
Diff
76 lines
3.3 KiB
Diff
From 079dfdbb94013e05660e54e6c7c3654468bc4160 Mon Sep 17 00:00:00 2001
|
|
From: Lynn Boger <laboger@linux.vnet.ibm.com>
|
|
Date: Thu, 29 Apr 2021 16:07:25 -0500
|
|
Subject: [PATCH] cmd/link/internal: fix use of DynlinkingGo with ppc64le
|
|
trampolines
|
|
|
|
When creating programs with large text sections on ppc64le,
|
|
trampolines are needed for calls that are too far; however
|
|
they are not created if the code is generated such that the TOC
|
|
register r2 is initialized and maintained in the code because
|
|
then the external linker can create the trampolines. Previously
|
|
the function DynlinkingGo was used to determine this but in the
|
|
case where plugins are used, this could return true even though
|
|
r2 is not valid.
|
|
|
|
To fix this problem I've added a new function r2Valid which returns
|
|
true when the build options indicate that the r2 is
|
|
initialized and maintained. Because of the ways that
|
|
DynlinkingGo is used I wanted to maintain its previous
|
|
behavior.
|
|
|
|
Fixes #45850
|
|
|
|
Change-Id: I6d902eba6ad41757aa6474948b79acdbd479cb38
|
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/315289
|
|
Trust: Lynn Boger <laboger@linux.vnet.ibm.com>
|
|
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
|
|
Reviewed-by: Cherry Zhang <cherryyz@google.com>
|
|
TryBot-Result: Go Bot <gobot@golang.org>
|
|
---
|
|
src/cmd/link/internal/ppc64/asm.go | 14 ++++++++++++--
|
|
1 file changed, 12 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
|
|
index 602f0b5299..539afac187 100644
|
|
--- a/src/cmd/link/internal/ppc64/asm.go
|
|
+++ b/src/cmd/link/internal/ppc64/asm.go
|
|
@@ -642,6 +642,16 @@ func archrelocaddr(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r l
|
|
return int64(o2)<<32 | int64(o1)
|
|
}
|
|
|
|
+// Determine if the code was compiled so that the TOC register R2 is initialized and maintained
|
|
+func r2Valid(ctxt *ld.Link) bool {
|
|
+ switch ctxt.BuildMode {
|
|
+ case ld.BuildModeCArchive, ld.BuildModeCShared, ld.BuildModePIE, ld.BuildModeShared, ld.BuildModePlugin:
|
|
+ return true
|
|
+ }
|
|
+ // -linkshared option
|
|
+ return ctxt.IsSharedGoLink()
|
|
+}
|
|
+
|
|
// resolve direct jump relocation r in s, and add trampoline if necessary
|
|
func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
|
|
|
|
@@ -649,7 +659,7 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
|
|
// For internal linking, trampolines are always created for long calls.
|
|
// For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
|
|
// r2. For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
|
|
- if ctxt.IsExternal() && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
|
|
+ if ctxt.IsExternal() && r2Valid(ctxt) {
|
|
// No trampolines needed since r2 contains the TOC
|
|
return
|
|
}
|
|
@@ -703,7 +713,7 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
|
|
}
|
|
}
|
|
if ldr.SymType(tramp) == 0 {
|
|
- if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
|
|
+ if r2Valid(ctxt) {
|
|
// Should have returned for above cases
|
|
ctxt.Errorf(s, "unexpected trampoline for shared or dynamic linking")
|
|
} else {
|
|
--
|
|
2.30.2
|
|
|