]> granicus.if.org Git - llvm/commitdiff
[ARM, ELF] Don't shift movt relocation offsets
authorMartin Storsjo <martin@martin.st>
Tue, 11 Jul 2017 21:07:10 +0000 (21:07 +0000)
committerMartin Storsjo <martin@martin.st>
Tue, 11 Jul 2017 21:07:10 +0000 (21:07 +0000)
For ELF, a movw+movt pair is handled as two separate relocations.
If an offset should be applied to the symbol address, this offset is
stored as an immediate in the instruction (as opposed to stored as an
offset in the relocation itself).

Even though the actual value stored in the movt immediate after linking
is the top half of the value, we need to store the unshifted offset
prior to linking. When the relocation is made during linking, the offset
gets added to the target symbol value, and the upper half of the value
is stored in the instruction.

This makes sure that movw+movt with offset symbols get properly
handled, in case the offset addition in the lower half should be
carried over to the upper half.

This makes the output from the additions to the test case match
the output from GNU binutils.

For COFF and MachO, the movw/movt relocations are handled as a pair,
and the overflow from the lower half gets carried over to the movt,
so they should keep the shifted offset just as before.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307713 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
test/MC/ARM/elf-movt.s

index 22de728fe06e1d25ccd8e91e026142a66dd9ef50..91174c800b2c70c3563fbeabe3dd70b4076eca95 100644 (file)
@@ -392,7 +392,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
   case FK_SecRel_4:
     return Value;
   case ARM::fixup_arm_movt_hi16:
-    if (!IsPCRel)
+    if (!IsPCRel && !STI->getTargetTriple().isOSBinFormatELF())
       Value >>= 16;
     LLVM_FALLTHROUGH;
   case ARM::fixup_arm_movw_lo16: {
@@ -404,7 +404,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
     return Value;
   }
   case ARM::fixup_t2_movt_hi16:
-    if (!IsPCRel)
+    if (!IsPCRel && !STI->getTargetTriple().isOSBinFormatELF())
       Value >>= 16;
     LLVM_FALLTHROUGH;
   case ARM::fixup_t2_movw_lo16: {
index 9df7a603b71a71f5b884b7b31c0f5afac2be4ad6..5e4d6e18db79c8b572725ccf3886a9871fbdfbe2 100644 (file)
@@ -14,8 +14,12 @@ barf:                                   @ @barf
        movw    r0, :lower16:GOT-(.LPC0_2+8)
        movt    r0, :upper16:GOT-(.LPC0_2+8)
 .LPC0_2:
+       movw    r0, :lower16:extern_symbol+1234
+       movt    r0, :upper16:extern_symbol+1234
 @ ASM:          movw    r0, :lower16:(GOT-(.LPC0_2+8))
 @ ASM-NEXT:     movt    r0, :upper16:(GOT-(.LPC0_2+8))
+@ ASM:          movw    r0, :lower16:(extern_symbol+1234)
+@ ASM-NEXT:     movt    r0, :upper16:(extern_symbol+1234)
 
 @OBJ:      Disassembly of section .text:
 @OBJ-NEXT: barf:
@@ -23,6 +27,10 @@ barf:                                   @ @barf
 @OBJ-NEXT: 00000000:         R_ARM_MOVW_PREL_NC   GOT
 @OBJ-NEXT: 4:             f4 0f 4f e3     movt    r0, #65524
 @OBJ-NEXT: 00000004:         R_ARM_MOVT_PREL      GOT
+@OBJ-NEXT: 8:             d2 04 00 e3     movw    r0, #1234
+@OBJ-NEXT: 00000008:         R_ARM_MOVW_ABS_NC    extern_symbol
+@OBJ-NEXT: c:             d2 04 40 e3     movt    r0, #1234
+@OBJ-NEXT: 0000000c:         R_ARM_MOVT_ABS       extern_symbol
 
 @THUMB:      Disassembly of section .text:
 @THUMB-NEXT: barf:
@@ -30,3 +38,7 @@ barf:                                   @ @barf
 @THUMB-NEXT: 00000000:         R_ARM_THM_MOVW_PREL_NC GOT
 @THUMB-NEXT: 4:             cf f6 f4 70     movt    r0, #65524
 @THUMB-NEXT: 00000004:         R_ARM_THM_MOVT_PREL    GOT
+@THUMB-NEXT: 8:             40 f2 d2 40     movw    r0, #1234
+@THUMB-NEXT: 00000008:         R_ARM_THM_MOVW_ABS_NC  extern_symbol
+@THUMB-NEXT: c:             c0 f2 d2 40     movt    r0, #1234
+@THUMB-NEXT: 0000000c:         R_ARM_THM_MOVT_ABS     extern_symbol