Switching to external relocations for ARM-mode branches (to allow Thumb
interworking when the offset is unencodable) causes calls to temporary symbols
to be miscompiled and instead go to the parent externally visible symbol.
Calling a temporary never happens in compiled code, but can occasionally in
hand-written assembly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311611
91177308-0d34-0410-b5e6-
96231b3b80d8
case MachO::ARM_RELOC_BR24:
// An ARM call might be to a Thumb function, in which case the offset may
// not be encodable in the instruction and we must use an external
- // relocation that explicitly mentions the function.
- return true;
+ // relocation that explicitly mentions the function. Not a problem if it's
+ // to a temporary "Lwhatever" symbol though, and in fact trying to use an
+ // external relocation there causes more issues.
+ if (!S.isTemporary())
+ return true;
+
+ // PC pre-adjustment of 8 for these instructions.
+ Value -= 8;
+ // ARM BL/BLX has a 25-bit offset.
+ Range = 0x1ffffff;
+ break;
case MachO::ARM_THUMB_RELOC_BR22:
// PC pre-adjustment of 4 for these instructions.
Value -= 4;
--- /dev/null
+@ RUN: llvm-mc -triple armv7-apple-ios -filetype=obj -o %t %s
+@ RUN: llvm-objdump -d -r %t | FileCheck %s
+
+@ CHECK: _func:
+@ CHECK: bl #0 <_func+0x8>
+@ CHECK: ARM_RELOC_BR24 __text
+@ CHECK: bl #-12 <_func>
+@ CHECK: ARM_RELOC_BR24 _elsewhere
+ .global _func
+_func:
+ bl Llocal_symbol
+ bl _elsewhere
+Llocal_symbol:
+ bx lr
+
+ .global _elsewhere
+_elsewhere:
+ bx lr