mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-07 13:39:43 +08:00
normally RELA relocs in BFD should not consider the contents of the relocated place. The aarch64 psABI is even stricter, it specifies (section 5.7.16) that all RELA relocs _must_ be idempotent. Since the inception of the aarch64 BFD backend all the relocs have a non-zero src_mask, and hence break this invariant. It's normally not a very visible problem as one can see it only when the relocated place already contains a non-zero value, which usually only happens sometimes when using 'ld -r' (or as in the testcase when jumping through hoops to generate the relocations). Or with alternative toolchains that do encode stuff in the relocated places with the assumption that a relocation to that place ignores whatever is there (as they can according to the psABI). Golang is such a toolchain and https://github.com/golang/go/issues/39927 is ultimately caused by this problem: the testcase testGCData failing is caused by the garbage collection data-structure to describe a type containing pointers to be wrong. It's wrong because a field that's supposed to contain a file-relative offset (to some gcbits) has a relocation applied and that relocation has an addend which also is already part of the go-produced object file (so the addend is implicitely applied twice). bfd/ PR ld/30437 * elfnn-aarch64.c (elfNN_aarch64_howto_table): Clear src_mask if all relocation descriptors. ld/ * testsuite/ld-aarch64/rela-idempotent.s: New testcase. * testsuite/ld-aarch64/rela-idempotent.d: New. * testsuite/ld-aarch64/aarch64-elf.exp: Run it.
15 lines
333 B
ArmAsm
15 lines
333 B
ArmAsm
# this checks that aarch64 RELA relocs are ignoring existing section
|
|
# content of the relocated place
|
|
.text
|
|
.global _start
|
|
_start:
|
|
ret
|
|
|
|
.data
|
|
.p2align 4
|
|
l: .long 0x11111111, 0x22222222
|
|
q: .quad 0x4444444433333333
|
|
|
|
.reloc l, BFD_RELOC_64, q+42
|
|
.reloc q, BFD_RELOC_64, l+84
|