diff options
author | Cherry Mui <cherryyz@google.com> | 2023-06-12 13:42:30 -0400 |
---|---|---|
committer | Cherry Mui <cherryyz@google.com> | 2023-08-02 17:38:41 +0000 |
commit | a3b092d65e2df7584e452508a6a1ddc0d861a010 (patch) | |
tree | 7a0d02c9c96b39e71e482345a5405657d7cc184e | |
parent | 07c72a0915093feb9837dbcbc963810a3efcb6b6 (diff) | |
download | go-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.go | 2 | ||||
-rw-r--r-- | src/cmd/link/internal/arm64/asm.go | 5 | ||||
-rw-r--r-- | src/cmd/link/internal/ld/data.go | 4 |
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() { |