[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