ARM: use internal relocations for local symbols after all.

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.

llvm-svn: 311611
This commit is contained in:
Tim Northover 2017-08-23 22:07:10 +00:00
parent 7db6b5e2b3
commit 4bafa16748
2 changed files with 29 additions and 2 deletions

View File

@ -324,8 +324,17 @@ bool ARMMachObjectWriter::requiresExternRelocation(MachObjectWriter *Writer,
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;

View File

@ -0,0 +1,18 @@
@ 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