1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

ARM: fix handling of movw/movt relocations with addend.

We were emitting only one half of a the paired relocations needed for these
instructions because we decided that an offset needed a scattered relocation.
In fact, movw/movt relocations can be paired without being scattered.

llvm-svn: 261679
This commit is contained in:
Tim Northover 2016-02-23 20:20:23 +00:00
parent 5377924081
commit ccd1c20321
2 changed files with 72 additions and 3 deletions

View File

@ -389,7 +389,8 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
uint32_t Offset = Target.getConstant();
if (IsPCRel && RelocType == MachO::ARM_RELOC_VANILLA)
Offset += 1 << Log2Size;
if (Offset && A && !Writer->doesSymbolRequireExternRelocation(*A))
if (Offset && A && !Writer->doesSymbolRequireExternRelocation(*A) &&
RelocType != MachO::ARM_RELOC_HALF)
return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
Target, RelocType, Log2Size,
FixedValue);
@ -447,8 +448,10 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
// Even when it's not a scattered relocation, movw/movt always uses
// a PAIR relocation.
if (Type == MachO::ARM_RELOC_HALF) {
// The other-half value only gets populated for the movt and movw
// relocation entries.
// The entire addend is needed to correctly apply a relocation. One half is
// extracted from the instruction itself, the other comes from this
// PAIR. I.e. it's correct that we insert the high bits of the addend in the
// MOVW case here. relocation entries.
uint32_t Value = 0;
switch ((unsigned)Fixup.getKind()) {
default: break;

66
test/MC/ARM/macho-movwt.s Normal file
View File

@ -0,0 +1,66 @@
@ RUN: llvm-mc -triple thumbv7s-apple-ios9.0 %s -filetype obj -o %t.o
@ RUN: llvm-readobj -r %t.o | FileCheck %s
.thumb
movw r0, :lower16:_x
movt r0, :upper16:_x
movw r0, :lower16:_x+4
movt r0, :upper16:_x+4
movw r0, :lower16:_x+0x10000
movt r0, :upper16:_x+0x10000
.arm
movw r0, :lower16:_x
movt r0, :upper16:_x
movw r0, :lower16:_x+4
movt r0, :upper16:_x+4
movw r0, :lower16:_x+0x10000
movt r0, :upper16:_x+0x10000
@ Enter the bizarre world of MachO relocations. First, they're in reverse order
@ to the actual instructions
@ First column on the second line is the "other half" of the addend, its partner
@ being in the instruction itself.
@ Third column identifies ARM/Thumb & HI/LO.
@ CHECK: 0x2C 0 1 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 1 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x28 0 0 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x1 0 0 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x24 0 1 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x4 0 1 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x20 0 0 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 0 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x1C 0 1 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 1 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x18 0 0 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 0 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x14 0 3 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 3 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x10 0 2 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x1 0 2 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0xC 0 3 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x4 0 3 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x8 0 2 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 2 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x4 0 3 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 3 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x0 0 2 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 2 0 ARM_RELOC_PAIR 0 -