Fix the alignment check.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 31 Mar 2016 12:09:36 +0000 (12:09 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 31 Mar 2016 12:09:36 +0000 (12:09 +0000)
We have to check the final value that is written.

I don't think this has any real word implications (unless something
supports unaligned instructions), but unblocks simplifying the handling
of PC relative relocations.

llvm-svn: 265009

lld/ELF/Target.cpp
lld/test/ELF/Inputs/mips-align-err.s [new file with mode: 0644]
lld/test/ELF/mips-align-err.s [new file with mode: 0644]

index 09e3ee6..f89c046 100644 (file)
@@ -1638,9 +1638,9 @@ static void applyMipsPcReloc(uint8_t *Loc, uint32_t Type, uint64_t P,
                              uint64_t SA) {
   uint32_t Mask = 0xffffffff >> (32 - BSIZE);
   uint32_t Instr = read32<E>(Loc);
-  if (SHIFT > 0)
-    checkAlignment<(1 << SHIFT)>(SA, Type);
   int64_t V = SA - P;
+  if (SHIFT > 0)
+    checkAlignment<(1 << SHIFT)>(V, Type);
   checkInt<BSIZE + SHIFT>(V, Type);
   write32<E>(Loc, (Instr & ~Mask) | ((V >> SHIFT) & Mask));
 }
diff --git a/lld/test/ELF/Inputs/mips-align-err.s b/lld/test/ELF/Inputs/mips-align-err.s
new file mode 100644 (file)
index 0000000..2d813b7
--- /dev/null
@@ -0,0 +1,2 @@
+        .global _foo
+_foo:
diff --git a/lld/test/ELF/mips-align-err.s b/lld/test/ELF/mips-align-err.s
new file mode 100644 (file)
index 0000000..28b192a
--- /dev/null
@@ -0,0 +1,12 @@
+# REQUIRES: mips
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o \
+# RUN:         -mcpu=mips32r6
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN:         -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o
+# RUN: not ld.lld %t.o %t2.o -o %t.exe 2>&1 | FileCheck %s
+# CHECK: improper alignment for relocation R_MIPS_PC16
+
+        .globl  __start
+__start:
+.zero 1
+        beqc      $5, $6, _foo            # R_MIPS_PC16