aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2023-06-12 13:42:30 -0400
committerCherry Mui <cherryyz@google.com>2023-08-02 17:38:41 +0000
commita3b092d65e2df7584e452508a6a1ddc0d861a010 (patch)
tree7a0d02c9c96b39e71e482345a5405657d7cc184e
parent07c72a0915093feb9837dbcbc963810a3efcb6b6 (diff)
downloadgo-a3b092d65e2df7584e452508a6a1ddc0d861a010.tar.gz
go-a3b092d65e2df7584e452508a6a1ddc0d861a010.zip
[release-branch.go1.21] cmd/link: use symbol-targeted relocation for initializers on Mach-O
Apple's new linker, ld-prime from Xcode 15 beta, when handling initializers in __mod_init_func, drops the offset in the data, resolving the relocation to the beginning of the section. The latest version of ld-prime rejects non-zero addend. We need to use symbol-targeted "external" relocations, so that it doesn't need an addend and can be resolved correctly. This also works fine with ld64. Fixes #60694. For #61229. Change-Id: Ida2be6aa4c91bfcd142b755e2ec63aabfbbd77a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/502616 Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> (cherry picked from commit bad9ca8a612f6fae85cfc25e07e69ed30384fc84) Reviewed-on: https://go-review.googlesource.com/c/go/+/514535
-rw-r--r--src/cmd/link/internal/amd64/asm.go2
-rw-r--r--src/cmd/link/internal/arm64/asm.go5
-rw-r--r--src/cmd/link/internal/ld/data.go4
3 files changed, 7 insertions, 4 deletions
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index c91e37584c..4d95f61647 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -446,7 +446,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
rs := r.Xsym
rt := r.Type
- if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_PCREL || rt == objabi.R_GOTPCREL || rt == objabi.R_CALL {
+ if rt == objabi.R_PCREL || rt == objabi.R_GOTPCREL || rt == objabi.R_CALL || ldr.SymType(rs) == sym.SHOSTOBJ || ldr.SymType(s) == sym.SINITARR {
if ldr.SymDynid(rs) < 0 {
ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
return false
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index 312ee27aa6..69d430b039 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -545,10 +545,11 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
}
}
- if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 ||
+ if rt == objabi.R_CALLARM64 ||
rt == objabi.R_ARM64_PCREL_LDST8 || rt == objabi.R_ARM64_PCREL_LDST16 ||
rt == objabi.R_ARM64_PCREL_LDST32 || rt == objabi.R_ARM64_PCREL_LDST64 ||
- rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL {
+ rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL ||
+ ldr.SymType(rs) == sym.SHOSTOBJ || ldr.SymType(s) == sym.SINITARR {
if ldr.SymDynid(rs) < 0 {
ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
return false
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index d651e2e346..21b2e9a9d4 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -368,7 +368,9 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
o = 0
}
} else if target.IsDarwin() {
- if ldr.SymType(rs) != sym.SHOSTOBJ {
+ if ldr.SymType(rs) != sym.SHOSTOBJ && ldr.SymType(s) != sym.SINITARR {
+ // ld-prime drops the offset in data for SINITARR. We need to use
+ // symbol-targeted relocation. See also machoreloc1.
o += ldr.SymValue(rs)
}
} else if target.IsWindows() {