Sign extend a value before passing it to the Target.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 1 Sep 2016 13:52:52 +0000 (13:52 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 1 Sep 2016 13:52:52 +0000 (13:52 +0000)
This is what InputSectionBase<ELFT>::relocate does and we need to be
consistent. The other option would be to be more explicit about which
relocations are signed and which are not, and sign extend only when
appropriated. That would require extending the target interface.

llvm-svn: 280366

lld/ELF/Thunks.cpp
lld/test/ELF/arm-thumb-interwork-thunk-range.s [new file with mode: 0644]

index 1ebbb17..50b05c7 100644 (file)
@@ -100,7 +100,8 @@ public:
 
 // ARM Target Thunks
 template <class ELFT> static uint64_t getARMThunkDestVA(const SymbolBody &S) {
-  return S.isInPlt() ? S.getPltVA<ELFT>() : S.getVA<ELFT>();
+  uint64_t V = S.isInPlt() ? S.getPltVA<ELFT>() : S.getVA<ELFT>();
+  return SignExtend64<32>(V);
 }
 
 template <class ELFT>
diff --git a/lld/test/ELF/arm-thumb-interwork-thunk-range.s b/lld/test/ELF/arm-thumb-interwork-thunk-range.s
new file mode 100644 (file)
index 0000000..9ef64c7
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -o %t -image-base=0x80000000
+
+// Test that when the thunk is at a high address we don't get confused with it
+// being out of range.
+
+.thumb
+.global _start
+_start:
+b.w foo
+
+.arm
+.weak foo
+foo: