diff options
| author | qmuntal <quimmuntal@gmail.com> | 2025-09-12 16:31:01 +0200 |
|---|---|---|
| committer | Quim Muntal <quimmuntal@gmail.com> | 2025-09-30 07:38:03 -0700 |
| commit | 7c8166d02d36a5dfcdbe3dd1b148412cceacf9f2 (patch) | |
| tree | c6c1d802834fb855e4e0251c149db6b57bf9974e /src/cmd | |
| parent | 6e95748335bdd074c5b48fe9c3af4ced18c388dd (diff) | |
| download | go-7c8166d02d36a5dfcdbe3dd1b148412cceacf9f2.tar.xz | |
cmd/link/internal/arm64: support Mach-O ARM64_RELOC_SUBTRACTOR in internal linking
ARM64_RELOC_SUBTRACTOR is the arm64 version of X86_64_RELOC_SUBTRACTOR, which
has been recently implemented in CL 660715.
The standard library still doesn't need it, but I've found it necessary
when statically linking against a library I own.
Change-Id: I138281b12f2304e3673f7dc92f7137e48bf68fdd
Reviewed-on: https://go-review.googlesource.com/c/go/+/703316
Reviewed-by: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/link/internal/arm64/asm.go | 22 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/macho.go | 1 |
2 files changed, 23 insertions, 0 deletions
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index b2572fd104..8d8ea8ac54 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -224,6 +224,28 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade } return true + case objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_SUBTRACTOR*2: + // ARM64_RELOC_SUBTRACTOR must be followed by ARM64_RELOC_UNSIGNED. + // The pair of relocations resolves to the difference between two + // symbol addresses (each relocation specifies a symbol). + outer, off := ld.FoldSubSymbolOffset(ldr, targ) + if outer != s { + // TODO: support subtracted symbol in different section. + ldr.Errorf(s, "unsupported ARM64_RELOC_SUBTRACTOR reloc: target %s, outer %s", ldr.SymName(targ), ldr.SymName(outer)) + break + } + su := ldr.MakeSymbolUpdater(s) + relocs := su.Relocs() + if rIdx+1 >= relocs.Count() || relocs.At(rIdx+1).Type() != objabi.MachoRelocOffset+ld.MACHO_ARM64_RELOC_UNSIGNED*2 || relocs.At(rIdx+1).Off() != r.Off() { + ldr.Errorf(s, "unexpected ARM64_RELOC_SUBTRACTOR reloc, must be followed by ARM64_RELOC_UNSIGNED at same offset") + break + } + su.SetRelocType(rIdx+1, objabi.R_PCREL) + su.SetRelocAdd(rIdx+1, r.Add()+int64(r.Off())+int64(r.Siz())-off) + // Remove the other relocation + su.SetRelocSiz(rIdx, 0) + return true + case objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_BRANCH26*2 + pcrel: su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_CALLARM64) diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 6920f42015..c262634666 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -106,6 +106,7 @@ const ( MACHO_ARM_RELOC_SECTDIFF = 2 MACHO_ARM_RELOC_BR24 = 5 MACHO_ARM64_RELOC_UNSIGNED = 0 + MACHO_ARM64_RELOC_SUBTRACTOR = 1 MACHO_ARM64_RELOC_BRANCH26 = 2 MACHO_ARM64_RELOC_PAGE21 = 3 MACHO_ARM64_RELOC_PAGEOFF12 = 4 |
