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 <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-04-27 17:11:03 -04:00
parent 657f58d845
commit 12eaefead4
2 changed files with 29 additions and 2 deletions

View file

@ -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)
}

View file

@ -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