[lld] r214277 - [mach-o] Fix arm interworking with movw/movt
Nick Kledzik
kledzik at apple.com
Tue Jul 29 18:41:38 PDT 2014
Author: kledzik
Date: Tue Jul 29 20:41:38 2014
New Revision: 214277
URL: http://llvm.org/viewvc/llvm-project?rev=214277&view=rev
Log:
[mach-o] Fix arm interworking with movw/movt
In some cases the address of a function will be materialized with a movw/movt
pair. If the function is a thumb function, the low bit needs to be set on
the movw immediate value.
Added:
lld/trunk/test/mach-o/arm-interworking-movw.yaml
Modified:
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=214277&r1=214276&r2=214277&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp Tue Jul 29 20:41:38 2014
@@ -830,6 +830,8 @@ void ArchHandler_arm::applyFixupFinal(co
case thumb_movw:
assert(thumbMode);
value16 = (targetAddress + ref.addend()) & 0xFFFF;
+ if (targetIsThumb)
+ value16 |= 1;
write32(*loc32, _swap, setWordFromThumbMov(*loc32, value16));
break;
case thumb_movt:
@@ -840,6 +842,8 @@ void ArchHandler_arm::applyFixupFinal(co
case thumb_movw_funcRel:
assert(thumbMode);
value16 = (targetAddress - inAtomAddress + ref.addend()) & 0xFFFF;
+ if (targetIsThumb)
+ value16 |= 1;
write32(*loc32, _swap, setWordFromThumbMov(*loc32, value16));
break;
case thumb_movt_funcRel:
@@ -856,6 +860,8 @@ void ArchHandler_arm::applyFixupFinal(co
case arm_movw:
assert(!thumbMode);
value16 = (targetAddress + ref.addend()) & 0xFFFF;
+ if (targetIsThumb)
+ value16 |= 1;
write32(*loc32, _swap, setWordFromArmMov(*loc32, value16));
break;
case arm_movt:
@@ -866,6 +872,8 @@ void ArchHandler_arm::applyFixupFinal(co
case arm_movw_funcRel:
assert(!thumbMode);
value16 = (targetAddress - inAtomAddress + ref.addend()) & 0xFFFF;
+ if (targetIsThumb)
+ value16 |= 1;
write32(*loc32, _swap, setWordFromArmMov(*loc32, value16));
break;
case arm_movt_funcRel:
Added: lld/trunk/test/mach-o/arm-interworking-movw.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/arm-interworking-movw.yaml?rev=214277&view=auto
==============================================================================
--- lld/trunk/test/mach-o/arm-interworking-movw.yaml (added)
+++ lld/trunk/test/mach-o/arm-interworking-movw.yaml Tue Jul 29 20:41:38 2014
@@ -0,0 +1,393 @@
+# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s \
+# RUN: && lld -flavor darwin -arch armv7 -dylib -print_atoms \
+# RUN: -sectalign __TEXT __text 0x1000 %t -o %t2 | FileCheck %s \
+# RUN: && llvm-objdump -d -macho -triple=armv7-apple-ios %t2 | FileCheck -check-prefix=ACODE %s \
+# RUN: && llvm-objdump -d -macho -triple=thumbv7-apple-ios %t2 | FileCheck -check-prefix=TCODE %s && cp %t2 /tmp/a.out
+#
+# Test thumb and arm branches round trip through -r.
+# Test bl/blx instructions are fixed up properly.
+#
+#
+
+--- !mach-o
+arch: armv7
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ alignment: 2
+ address: 0x0000000000000000
+ content: [ 0x40, 0xF2, 0x25, 0x00, 0xC0, 0xF2, 0x00, 0x00,
+ 0x40, 0xF2, 0x01, 0x01, 0xC0, 0xF2, 0x00, 0x01,
+ 0x40, 0xF2, 0x4E, 0x02, 0xC0, 0xF2, 0x00, 0x02,
+ 0x40, 0xF2, 0x2A, 0x03, 0xC0, 0xF2, 0x00, 0x03,
+ 0x78, 0x44, 0x70, 0x47, 0x70, 0x47, 0x25, 0x00,
+ 0x00, 0xE3, 0x00, 0x00, 0x40, 0xE3, 0xD7, 0x1F,
+ 0x0F, 0xE3, 0xFF, 0x1F, 0x4F, 0xE3, 0x4E, 0x20,
+ 0x00, 0xE3, 0x00, 0x20, 0x40, 0xE3, 0x00, 0x30,
+ 0x00, 0xE3, 0x00, 0x30, 0x40, 0xE3, 0x0F, 0x00,
+ 0x80, 0xE0, 0x1E, 0xFF, 0x2F, 0xE1, 0x1E, 0xFF,
+ 0x2F, 0xE1 ]
+ relocations:
+ - offset: 0x00000042
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 1
+ pc-rel: false
+ value: 0x0000004E
+ - offset: 0x00000000
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 1
+ pc-rel: false
+ value: 0x00000046
+ - offset: 0x0000003E
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 0
+ pc-rel: false
+ value: 0x0000004E
+ - offset: 0x00000000
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 0
+ pc-rel: false
+ value: 0x00000046
+ - offset: 0x0000003A
+ type: ARM_RELOC_HALF
+ length: 1
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x0000004E
+ type: ARM_RELOC_PAIR
+ length: 1
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x00000036
+ type: ARM_RELOC_HALF
+ length: 0
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000000
+ type: ARM_RELOC_PAIR
+ length: 0
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x00000032
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 1
+ pc-rel: false
+ value: 0x00000024
+ - offset: 0x0000FFD6
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 1
+ pc-rel: false
+ value: 0x00000046
+ - offset: 0x0000002E
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 0
+ pc-rel: false
+ value: 0x00000024
+ - offset: 0x0000FFFF
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 0
+ pc-rel: false
+ value: 0x00000046
+ - offset: 0x0000002A
+ type: ARM_RELOC_HALF
+ length: 1
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000025
+ type: ARM_RELOC_PAIR
+ length: 1
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x00000026
+ type: ARM_RELOC_HALF
+ length: 0
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000000
+ type: ARM_RELOC_PAIR
+ length: 0
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x0000001C
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 3
+ pc-rel: false
+ value: 0x0000004E
+ - offset: 0x0000002A
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 3
+ pc-rel: false
+ value: 0x00000020
+ - offset: 0x00000018
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 2
+ pc-rel: false
+ value: 0x0000004E
+ - offset: 0x00000000
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 2
+ pc-rel: false
+ value: 0x00000020
+ - offset: 0x00000014
+ type: ARM_RELOC_HALF
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x0000004E
+ type: ARM_RELOC_PAIR
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x00000010
+ type: ARM_RELOC_HALF
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000000
+ type: ARM_RELOC_PAIR
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x0000000C
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 3
+ pc-rel: false
+ value: 0x00000024
+ - offset: 0x00000000
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 3
+ pc-rel: false
+ value: 0x00000020
+ - offset: 0x00000008
+ scattered: true
+ type: ARM_RELOC_HALF_SECTDIFF
+ length: 2
+ pc-rel: false
+ value: 0x00000024
+ - offset: 0x00000000
+ scattered: true
+ type: ARM_RELOC_PAIR
+ length: 2
+ pc-rel: false
+ value: 0x00000020
+ - offset: 0x00000004
+ type: ARM_RELOC_HALF
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000025
+ type: ARM_RELOC_PAIR
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+ - offset: 0x00000000
+ type: ARM_RELOC_HALF
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000000
+ type: ARM_RELOC_PAIR
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 16777215
+local-symbols:
+ - name: _t1
+ type: N_SECT
+ sect: 1
+ desc: [ N_ARM_THUMB_DEF ]
+ value: 0x0000000000000000
+ - name: _t2
+ type: N_SECT
+ sect: 1
+ desc: [ N_ARM_THUMB_DEF ]
+ value: 0x0000000000000024
+ - name: _a2
+ type: N_SECT
+ sect: 1
+ value: 0x000000000000004E
+ - name: _a1
+ type: N_SECT
+ sect: 1
+ value: 0x0000000000000026
+...
+
+# CHECK: defined-atoms:
+# CHECK: - name: _t1
+# CHECK: references:
+# CHECK: - kind: modeThumbCode
+# CHECK: offset: 0
+# CHECK: target: _t1
+# CHECK: - kind: thumb_movw
+# CHECK: offset: 0
+# CHECK: target: _t2
+# CHECK-NOT: addend:
+# CHECK: - kind: thumb_movt
+# CHECK: offset: 4
+# CHECK: target: _t2
+# CHECK-NOT: addend:
+# CHECK: - kind: thumb_movw_funcRel
+# CHECK: offset: 8
+# CHECK: target: _t2
+# CHECK: addend: -36
+# CHECK: - kind: thumb_movt_funcRel
+# CHECK: offset: 12
+# CHECK: target: _t2
+# CHECK: addend: -36
+# CHECK: - kind: thumb_movw
+# CHECK: offset: 16
+# CHECK: target: _a2
+# CHECK-NOT: addend:
+# CHECK: - kind: thumb_movt
+# CHECK: offset: 20
+# CHECK: target: _a2
+# CHECK-NOT: addend:
+# CHECK: - kind: thumb_movw_funcRel
+# CHECK: offset: 24
+# CHECK: target: _a2
+# CHECK: addend: -36
+# CHECK: - kind: thumb_movt_funcRel
+# CHECK: offset: 28
+# CHECK: target: _a2
+# CHECK: addend: -36
+# CHECK: - name: _t2
+# CHECK: references:
+# CHECK: - kind: modeThumbCode
+# CHECK: offset: 0
+# CHECK: target: _t2
+# CHECK: - name: _a1
+# CHECK: references:
+# CHECK: - kind: arm_movw
+# CHECK: offset: 0
+# CHECK: target: _t2
+# CHECK-NOT: addend:
+# CHECK: - kind: arm_movt
+# CHECK: offset: 4
+# CHECK: target: _t2
+# CHECK-NOT: addend:
+# CHECK: - kind: arm_movw_funcRel
+# CHECK: offset: 8
+# CHECK: target: _t2
+# CHECK: addend: -40
+# CHECK: - kind: arm_movt_funcRel
+# CHECK: offset: 12
+# CHECK: target: _t2
+# CHECK: addend: -40
+# CHECK: - kind: arm_movw
+# CHECK: offset: 16
+# CHECK: target: _a2
+# CHECK-NOT: addend:
+# CHECK: - kind: arm_movt
+# CHECK: offset: 20
+# CHECK: target: _a2
+# CHECK-NOT: addend:
+# CHECK: - kind: arm_movw_funcRel
+# CHECK: offset: 24
+# CHECK: target: _a2
+# CHECK: addend: -40
+# CHECK: - kind: arm_movt_funcRel
+# CHECK: offset: 28
+# CHECK: target: _a2
+# CHECK: addend: -40
+# CHECK: - name: _a2
+
+
+# TCODE: _t1:
+# TCODE-NEXT: movw r0, #4133
+# TCODE-NEXT: movt r0, #0
+# TCODE-NEXT: movw r1, #1
+# TCODE-NEXT: movt r1, #0
+# TCODE-NEXT: movw r2, #4174
+# TCODE-NEXT: movt r2, #0
+# TCODE-NEXT: movw r3, #42
+# TCODE-NEXT: movt r3, #0
+
+
+# ACODE: _a1:
+# ACODE-NEXT: movw r0, #4133
+# ACODE-NEXT: movt r0, #0
+# ACODE-NEXT: movw r1, #65495
+# ACODE-NEXT: movt r1, #65535
+# ACODE-NEXT: movw r2, #4174
+# ACODE-NEXT: movt r2, #0
+# ACODE-NEXT: movw r3, #0
+# ACODE-NEXT: movt r3, #0
+
+
+
+# .syntax unified
+# .align 2
+#
+# .code 16
+# .thumb_func _t1
+#_t1:
+# movw r0, :lower16:(_t2)
+# movt r0, :upper16:(_t2)
+# movw r1, :lower16:(_t2-(L0+4))
+# movt r1, :upper16:(_t2-(L0+4))
+# movw r2, :lower16:(_a2)
+# movt r2, :upper16:(_a2)
+# movw r3, :lower16:(_a2-(L0+4))
+# movt r3, :upper16:(_a2-(L0+4))
+#L0:
+# add r0, pc
+# bx lr
+#
+#
+# .code 16
+# .thumb_func _t2
+#_t2:
+# bx lr
+#
+#
+#
+# .code 32
+#_a1:
+# movw r0, :lower16:(_t2)
+# movt r0, :upper16:(_t2)
+# movw r1, :lower16:(_t2-(L1+8))
+# movt r1, :upper16:(_t2-(L1+8))
+# movw r2, :lower16:(_a2)
+# movt r2, :upper16:(_a2)
+# movw r3, :lower16:(_a2-(L1+8))
+# movt r3, :upper16:(_a2-(L1+8))
+#L1:
+# add r0, pc
+# bx lr
+#
+#_a2:
+# bx lr
+
More information about the llvm-commits
mailing list