[COFF, ARM64] Fix symbol offsets in ADRP/ADD/LDR/STR relocations
commit39726b8c26bc892902fc1361b12138235606535e
authorMartin Storsjo <martin@martin.st>
Wed, 26 Jul 2017 11:19:17 +0000 (26 11:19 +0000)
committerMartin Storsjo <martin@martin.st>
Wed, 26 Jul 2017 11:19:17 +0000 (26 11:19 +0000)
tree2b6baa7e7b0316874e19680762edf181410dcdf6
parentb04f6b41eb84d183a173e4099e4205704b5f1567
[COFF, ARM64] Fix symbol offsets in ADRP/ADD/LDR/STR relocations

In COFF, a symbol offset can't be stored in the relocation (as is
done in ELF or MachO), but is stored as the immediate in the
instruction itself. The immediate in the ADRP thus is the symbol
offset in bytes, not in pages. For the PAGEOFFSET_12A/L relocations,
ignore any offset outside of the lowest 12 bits; they won't have any
effect on the ADD/LDR/STR instruction itself but only on the associated
ADRP.

This is similar to how the same issue is handled for MOVW/MOVT
instructions in ELF (see e.g. SVN r307713, and r307728 in lld).

This fixes "fixup out of range" errors while building larger object
files, where temporary symbols end up as a plain section symbol and
an offset, and fixes any cases where the symbol offset mean that
the actual target ended up on a different page than the symbol
itself.

Differential Revision: https://reviews.llvm.org/D35791

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309105 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
test/MC/AArch64/coff-relocations.s
test/MC/AArch64/fixup-out-of-range.s