From: Michael Hudson-Doyle Date: Mon, 2 Nov 2015 21:23:56 +0000 (+1300) Subject: cmd/link: work around arm64 linker bugs with GOT relocations against local symbols X-Git-Tag: go1.6beta1~443 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4bae454d6865b64d189b797f4870a6c9eeb8212d;p=gostls13.git cmd/link: work around arm64 linker bugs with GOT relocations against local symbols Change-Id: Ie14530c57720f1af1960ab77686b860e906058c6 Reviewed-on: https://go-review.googlesource.com/16582 Reviewed-by: Russ Cox --- diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 844a363d7a..0e5a2d0a63 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -241,8 +241,38 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { default: return -1 - case obj.R_ADDRARM64, - obj.R_ARM64_GOTPCREL: + case obj.R_ARM64_GOTPCREL: + var o1, o2 uint32 + if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { + o1 = uint32(*val >> 32) + o2 = uint32(*val) + } else { + o1 = uint32(*val) + o2 = uint32(*val >> 32) + } + // Any relocation against a function symbol is redirected to + // be against a local symbol instead (see putelfsym in + // symtab.go) but unfortunately the system linker was buggy + // when confronted with a R_AARCH64_ADR_GOT_PAGE relocation + // against a local symbol until May 2015 + // (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So + // we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp; + // add + R_ADDRARM64. + if !(r.Sym.Version != 0 || (r.Sym.Type&obj.SHIDDEN != 0) || r.Sym.Local) && r.Sym.Type == obj.STEXT && ld.DynlinkingGo() { + if o2&0xffc00000 != 0xf9400000 { + ld.Ctxt.Diag("R_ARM64_GOTPCREL against unexpected instruction %x", o2) + } + o2 = 0x91000000 | (o2 & 0x000003ff) + r.Type = obj.R_ADDRARM64 + } + if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { + *val = int64(o1)<<32 | int64(o2) + } else { + *val = int64(o2)<<32 | int64(o1) + } + fallthrough + + case obj.R_ADDRARM64: r.Done = 0 // set up addend for eventual relocation via outer symbol.