From 12eaefead46d7ba10fce622f093d4c9b2989a5c0 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Tue, 27 Apr 2021 17:11:03 -0400 Subject: [PATCH] cmd/link: support trampoline insertion for PLT calls on ARM This is CL 314452, for ARM. Fixes #30949. Change-Id: Ib4e46a5bd11c698c4f8ea3bc4e7a605d7a538efc Reviewed-on: https://go-review.googlesource.com/c/go/+/314455 Trust: Cherry Zhang Reviewed-by: Than McIntosh --- src/cmd/link/internal/arm/asm.go | 25 +++++++++++++++++++++++-- src/cmd/link/internal/ld/data.go | 6 ++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 33b20febd7..ab780214bb 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -111,7 +111,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade return false } - // Handle relocations found in ELF object files. + // Handle relocations found in ELF object files. case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PLT32): su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_CALLARM) @@ -237,6 +237,21 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade su.SetRelocSym(rIdx, 0) return true } + + case objabi.R_GOTPCREL: + if target.IsExternal() { + // External linker will do this relocation. + return true + } + if targType != sym.SDYNIMPORT { + ldr.Errorf(s, "R_GOTPCREL target is not SDYNIMPORT symbol: %v", ldr.SymName(targ)) + } + ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT)) + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_PCREL) + su.SetRelocSym(rIdx, syms.GOT) + su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))) + return true } return false @@ -369,6 +384,12 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { relocs := ldr.Relocs(s) r := relocs.At(ri) switch r.Type() { + case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL), + objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24), + objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24): + // Host object relocations that will be turned into a PLT call. + // The PLT may be too far. Insert a trampoline for them. + fallthrough case objabi.R_CALLARM: var t int64 // ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet @@ -415,7 +436,7 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { // trampoline does not exist, create one trampb := ldr.MakeSymbolUpdater(tramp) ctxt.AddTramp(trampb) - if ctxt.DynlinkingGo() { + if ctxt.DynlinkingGo() || ldr.SymType(rs) == sym.SDYNIMPORT { if immrot(uint32(offset)) == 0 { ctxt.Errorf(s, "odd offset in dynlink direct call: %v+%d", ldr.SymName(rs), offset) } diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 1b5eb2f7e3..1c3af94692 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -134,6 +134,12 @@ func isPLTCall(rt objabi.RelocType) bool { objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26), objabi.MachoRelocOffset + MACHO_ARM64_RELOC_BRANCH26*2 + pcrel: return true + + // ARM + case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL), + objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24), + objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24): + return true } // TODO: other architectures. return false -- 2.50.0