MC: correct IMAGE_REL_ARM_MOV32T relocation emission
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 21 May 2014 23:17:56 +0000 (23:17 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 21 May 2014 23:17:56 +0000 (23:17 +0000)
This corrects the emission of IMAGE_REL_ARM_MOV32T relocations.  Previously, we
were avoiding the high portion of the relocation too early.  If there was a
section-relative relocation with an offset greater than 16-bits (65535), you
would end up truncating the high order bits of the offset.  Allow the current
relocation representation to flow through out the MC layer to the object writer.
Use the new ability to restrict recorded relocations to avoid emitting the
relocation into the final object.

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

lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
test/MC/ARM/Windows/mov32t-range.s [new file with mode: 0644]

index 701a6320d487a6e7b8472430411dcf104b8d4ff3..5b51a52f828a2d010838443c32ad8905189d469b 100644 (file)
@@ -1029,9 +1029,6 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
     switch (ARM16Expr->getKind()) {
     default: llvm_unreachable("Unsupported ARMFixup");
     case ARMMCExpr::VK_ARM_HI16:
-      if (Triple(STI.getTargetTriple()).isOSWindows())
-        return 0;
-
       Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16
                                        : ARM::fixup_arm_movt_hi16);
       break;
index ba9df6e962c944873563e782e89517895137cfef..d31f1f41c697f99c492bf3bfb8fd2dc12a6a648e 100644 (file)
@@ -27,6 +27,8 @@ public:
 
   unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
                         bool IsCrossSection) const override;
+
+  bool recordRelocation(const MCFixup &) const override;
 };
 
 unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
@@ -61,12 +63,14 @@ unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
   case ARM::fixup_arm_thumb_blx:
     return COFF::IMAGE_REL_ARM_BLX23T;
   case ARM::fixup_t2_movw_lo16:
-    return COFF::IMAGE_REL_ARM_MOV32T;
   case ARM::fixup_t2_movt_hi16:
-    llvm_unreachable("High-word for pair-wise relocations are contiguously "
-                     "addressed as an IMAGE_REL_ARM_MOV32T relocation");
+    return COFF::IMAGE_REL_ARM_MOV32T;
   }
 }
+
+bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const {
+  return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16;
+}
 }
 
 namespace llvm {
diff --git a/test/MC/ARM/Windows/mov32t-range.s b/test/MC/ARM/Windows/mov32t-range.s
new file mode 100644 (file)
index 0000000..fef8ff2
--- /dev/null
@@ -0,0 +1,37 @@
+@ RUN: llvm-mc -triple thumbv7-windows-itanium -filetype obj -o - %s \
+@ RUN:   | llvm-readobj -r - | FileCheck -check-prefix CHECK-RELOCATIONS %s
+
+@ RUN: llvm-mc -triple thumbv7-windows-itanium -filetype obj -o - %s \
+@ RUN:   | llvm-objdump -d - | FileCheck -check-prefix CHECK-ENCODING %s
+
+       .syntax unified
+       .thumb
+       .text
+
+       .def truncation
+               .scl 3
+               .type 32
+       .endef
+       .align 2
+       .thumb_func
+truncation:
+       movw r0, :lower16:.Lerange
+       movt r0, :upper16:.Lerange
+       bx lr
+
+       .section .rdata,"rd"
+.Lbuffer:
+       .zero 65536
+.Lerange:
+       .asciz "-erange"
+
+@ CHECK-RELOCATIONS: Relocations [
+@ CHECK-RELOCATIONS:   .text {
+@ CHECK-RELOCATIONS:     0x0 IMAGE_REL_ARM_MOV32T .rdata
+@ CHECK-RELOCATIONS-NOT: 0x4 IMAGE_REL_ARM_MOV32T .rdata
+@ CHECK-RELOCATIONS:   }
+@ CHECK-RELOCATIONS: ]
+
+@ CHECK-ENCODING:      0: 40 f2 00 00
+@ CHECK-ENCODING-NEXT: 4: c0 f2 01 00
+