[lld] r272881 - Add initial support for Thumb for ARMv7a

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 16 02:53:49 PDT 2016


Author: psmith
Date: Thu Jun 16 04:53:46 2016
New Revision: 272881

URL: http://llvm.org/viewvc/llvm-project?rev=272881&view=rev
Log:
    Add initial support for Thumb for ARMv7a
    
    Add support for the R_ARM_THM relocations used in the objects present
    in arm-linux-gnueabihf-gcc. These are:
    R_ARM_THM_CALL
    R_ARM_THM_JUMP11
    R_ARM_THM_JUMP19
    R_ARM_THM_JUMP24
    R_ARM_THM_MOVT_ABS
    R_ARM_THM_MOVW_ABS_NC
    
    Interworking between ARM and Thumb is partially supported with BLX.
    The R_ARM_CALL relocation for ARM instructions and R_ARM_THM_CALL
    relocation for Thumb instructions will write out a BL or BLX depending
    on the state of the Target.
    
    Assumptions:
    - Availability of BLX and extended range of Thumb 4-byte Branch
      instructions.
    - In relocateOne if (Val & 0x1) == 1 target is Thumb, 0 is ARM.
      This will hold for objects that comply with the ABI for the
      ARM architecture.
    
    This is sufficient for hello world to work with a recent
    arm-linux-gnueabihf distribution.
    
    Limitations:
    No interworking for R_ARM_JUMP24, R_ARM_THM_JUMP24, R_ARM_THM_JUMP19
    and the deprecated R_ARM_PLT32 and R_ARM_PC24 instructions as these
    cannot be written out as a BLX and need a state change thunk.
    
    No range extension thunks. The R_ARM_JUMP24 and R_ARM_THM_CALL have a
    range of 16Mb


Added:
    lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s   (with props)
    lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.o   (with props)
    lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s   (with props)
    lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s   (with props)
    lld/trunk/test/ELF/arm-blx.s   (with props)
    lld/trunk/test/ELF/arm-thumb-blx.s   (with props)
    lld/trunk/test/ELF/arm-thumb-branch-error.s   (with props)
    lld/trunk/test/ELF/arm-thumb-branch.s   (with props)
    lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s   (with props)
    lld/trunk/test/ELF/arm-thumb-plt-reloc.s   (with props)
Modified:
    lld/trunk/ELF/Target.cpp
    lld/trunk/test/ELF/arm-mov-relocs.s

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=272881&r1=272880&r2=272881&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Jun 16 04:53:46 2016
@@ -1460,10 +1460,15 @@ RelExpr ARMTargetInfo::getRelExpr(uint32
   switch (Type) {
   default:
     return R_ABS;
+  case R_ARM_THM_JUMP11:
+    return R_PC;
   case R_ARM_CALL:
   case R_ARM_JUMP24:
   case R_ARM_PC24:
   case R_ARM_PLT32:
+  case R_ARM_THM_JUMP19:
+  case R_ARM_THM_JUMP24:
+  case R_ARM_THM_CALL:
     return R_PLT_PC;
   case R_ARM_GOTOFF32:
     // (S + A) - GOT_ORG
@@ -1546,12 +1551,70 @@ void ARMTargetInfo::relocateOne(uint8_t
     write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
     break;
   case R_ARM_CALL:
+    // R_ARM_CALL is used for BL and BLX instructions, depending on the
+    // value of bit 0 of Val, we must select a BL or BLX instruction
+    if (Val & 1) {
+      // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
+      // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
+      checkInt<26>(Val, Type);
+      write32le(Loc, 0xfa000000 |                    // opcode
+                         ((Val & 2) << 23) |         // H
+                         ((Val >> 2) & 0x00ffffff)); // imm24
+      break;
+    }
+    if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
+      // BLX (always unconditional) instruction to an ARM Target, select an
+      // unconditional BL.
+      write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
+    // fall through as BL encoding is shared with B
   case R_ARM_JUMP24:
   case R_ARM_PC24:
   case R_ARM_PLT32:
     checkInt<26>(Val, Type);
     write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
     break;
+  case R_ARM_THM_JUMP11:
+    checkInt<12>(Val, Type);
+    write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
+    break;
+  case R_ARM_THM_JUMP19:
+    // Encoding T3: Val = S:J2:J1:imm6:imm11:0
+    checkInt<21>(Val, Type);
+    write16le(Loc,
+              (read16le(Loc) & 0xfbc0) |   // opcode cond
+                  ((Val >> 10) & 0x0400) | // S
+                  ((Val >> 12) & 0x003f)); // imm6
+    write16le(Loc + 2,
+              0x8000 |                    // opcode
+                  ((Val >> 8) & 0x0800) | // J2
+                  ((Val >> 5) & 0x2000) | // J1
+                  ((Val >> 1) & 0x07ff)); // imm11
+    break;
+  case R_ARM_THM_CALL:
+    // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
+    // value of bit 0 of Val, we must select a BL or BLX instruction
+    if ((Val & 1) == 0) {
+      // Ensure BLX destination is 4-byte aligned. As BLX instruction may
+      // only be two byte aligned. This must be done before overflow check
+      Val = alignTo(Val, 4);
+    }
+    // Bit 12 is 0 for BLX, 1 for BL
+    write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
+    // Fall through as rest of encoding is the same as B.W
+  case R_ARM_THM_JUMP24:
+    // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
+    // FIXME: Use of I1 and I2 require v6T2ops
+    checkInt<25>(Val, Type);
+    write16le(Loc,
+              0xf000 |                     // opcode
+                  ((Val >> 14) & 0x0400) | // S
+                  ((Val >> 12) & 0x03ff)); // imm10
+    write16le(Loc + 2,
+              (read16le(Loc + 2) & 0xd000) |                  // opcode
+                  (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
+                  (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
+                  ((Val >> 1) & 0x07ff));                     // imm11
+    break;
   case R_ARM_MOVW_ABS_NC:
     write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
                        (Val & 0x0fff));
@@ -1561,6 +1624,29 @@ void ARMTargetInfo::relocateOne(uint8_t
     write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
                        (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
     break;
+  case R_ARM_THM_MOVT_ABS:
+    // Encoding T1: A = imm4:i:imm3:imm8
+    checkUInt<32>(Val, Type);
+    write16le(Loc,
+              0xf2c0 |                     // opcode
+                  ((Val >> 17) & 0x0400) | // i
+                  ((Val >> 28) & 0x000f)); // imm4
+    write16le(Loc + 2,
+              (read16le(Loc + 2) & 0x8f00) | // opcode
+                  ((Val >> 12) & 0x7000) |   // imm3
+                  ((Val >> 16) & 0x00ff));   // imm8
+    break;
+  case R_ARM_THM_MOVW_ABS_NC:
+    // Encoding T3: A = imm4:i:imm3:imm8
+    write16le(Loc,
+              0xf240 |                     // opcode
+                  ((Val >> 1) & 0x0400) |  // i
+                  ((Val >> 12) & 0x000f)); // imm4
+    write16le(Loc + 2,
+              (read16le(Loc + 2) & 0x8f00) | // opcode
+                  ((Val << 4) & 0x7000) |    // imm3
+                  (Val & 0x00ff));           // imm8
+    break;
   default:
     fatal("unrecognized reloc " + Twine(Type));
   }
@@ -1585,13 +1671,48 @@ uint64_t ARMTargetInfo::getImplicitAdden
   case R_ARM_PC24:
   case R_ARM_PLT32:
     return SignExtend64<26>((read32le(Buf) & 0x00ffffff) << 2);
+  case R_ARM_THM_JUMP11:
+    return SignExtend64<12>((read16le(Buf) & 0x07ff) << 1);
+  case R_ARM_THM_JUMP19: {
+    // Encoding T3: A = S:J2:J1:imm10:imm6:0
+    uint16_t Hi = read16le(Buf);
+    uint16_t Lo = read16le(Buf + 2);
+    return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
+                            ((Lo & 0x0800) << 8) |  // J2
+                            ((Lo & 0x2000) << 5) |  // J1
+                            ((Hi & 0x003f) << 12) | // imm6
+                            ((Lo & 0x07ff) << 1));  // imm11:0
+  }
+  case R_ARM_THM_JUMP24:
+  case R_ARM_THM_CALL: {
+    // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
+    // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
+    // FIXME: I1 and I2 require v6T2ops
+    uint16_t Hi = read16le(Buf);
+    uint16_t Lo = read16le(Buf + 2);
+    return SignExtend64<24>(((Hi & 0x0400) << 14) |                    // S
+                            (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
+                            (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
+                            ((Hi & 0x003ff) << 12) |                   // imm0
+                            ((Lo & 0x007ff) << 1)); // imm11:0
+  }
+  // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
+  // MOVT is in the range -32768 <= A < 32768
   case R_ARM_MOVW_ABS_NC:
   case R_ARM_MOVT_ABS: {
-    // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
-    // MOVT is in the range -32768 <= A < 32768
     uint64_t Val = read32le(Buf) & 0x000f0fff;
     return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
   }
+  case R_ARM_THM_MOVW_ABS_NC:
+  case R_ARM_THM_MOVT_ABS: {
+    // Encoding T3: A = imm4:i:imm3:imm8
+    uint16_t Hi = read16le(Buf);
+    uint16_t Lo = read16le(Buf + 2);
+    return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
+                            ((Hi & 0x0400) << 1) |  // i
+                            ((Lo & 0x7000) >> 4) |  // imm3
+                            (Lo & 0x00ff));         // imm8
+  }
   }
 }
 

Added: lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,36 @@
+ .syntax unified
+ .arm
+ .section .R_ARM_CALL24_callee_low, "ax",%progbits
+ .align 2
+ .globl callee_low
+ .type callee_low,%function
+callee_low:
+ bx lr
+
+ .section .R_ARM_CALL24_callee_thumb_low, "ax",%progbits
+ .balign 0x100
+ .thumb
+ .type callee_thumb_low,%function
+ .globl callee_thumb_low
+callee_thumb_low:
+  bx lr
+
+ .section .R_ARM_CALL24_callee_high, "ax",%progbits
+ .balign 0x100
+ .arm
+ .globl callee_high
+ .type callee_high,%function
+callee_high:
+ bx lr
+
+ .section .R_ARM_CALL24_callee_thumb_high, "ax",%progbits
+ .balign 0x100
+ .thumb
+ .type callee_thumb_high,%function
+ .globl callee_thumb_high
+callee_thumb_high:
+  bx lr
+
+ .globl blx_far
+ .type   blx_far, %function
+blx_far = 0x1010018

Propchange: lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/Inputs/arm-thumb-blx-targets.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.o?rev=272881&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.o
------------------------------------------------------------------------------
    svn:mime-type = application/x-object

Added: lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,18 @@
+// This input must be assembled by the GNU assembler, as llvm-mc does not emit
+// the R_ARM_JUMP11 relocation for a Thumb narrow branch. This is permissible
+// by the ABI for the ARM architecture as the range of the Thumb narrow branch
+// is short enough (+- 2048 bytes) that widespread use would be impractical.
+//
+// The test case will use a pre compiled object arm-thumb-narrow-branch.o
+ .syntax unified
+ .section .caller, "ax",%progbits
+ .thumb
+ .align 2
+ .type callers,%function
+ .globl callers
+callers:
+ b.n callee_low_far
+ b.n callee_low
+ b.n callee_high
+ b.n callee_high_far
+ bx lr

Propchange: lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/Inputs/arm-thumb-narrow-branch.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s (added)
+++ lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,24 @@
+.global far_cond
+.type far_cond,%function
+far_cond = 0x110023
+.global far_uncond
+.type far_uncond,%function
+far_uncond = 0x101001b
+
+.global too_far1
+.type too_far1,%function
+too_far1 = 0x1020005
+.global too_far2
+.type too_far1,%function
+too_far2 = 0x1020009
+.global too_far3
+.type too_far3,%function
+too_far3 = 0x12000d
+
+.global blx_far
+.type   blx_far, %function
+blx_far = 0x2010025
+
+.global blx_far2
+.type   blx_far2, %function
+blx_far2 = 0x2010029

Propchange: lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/Inputs/far-arm-thumb-abs.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/arm-blx.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-blx.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-blx.s (added)
+++ lld/trunk/test/ELF/arm-blx.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,113 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: echo "SECTIONS { \
+// RUN:          .callee1 : { *(.callee_low) } \
+// RUN:          .callee2 : { *(.callee_arm_low) } \
+// RUN:          .caller : { *(.text) } \
+// RUN:          .callee3 : { *(.callee_high) } \
+// RUN:          .callee4 : { *(.callee_arm_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
+// REQUIRES: arm
+
+// Test BLX instruction is chosen for ARM BL/BLX instruction and Thumb callee
+// Using two callees to ensure at least one has 2-byte alignment.
+ .syntax unified
+ .thumb
+ .section .callee_low, "ax",%progbits
+ .align 2
+ .type callee_low,%function
+callee_low:
+ bx lr
+ .type callee_low2, %function
+callee_low2:
+ bx lr
+
+ .section .callee_arm_low, "ax",%progbits
+ .arm
+ .balign 0x100
+ .type callee_arm_low,%function
+ .align 2
+callee_arm_low:
+  bx lr
+
+.section .text, "ax",%progbits
+ .arm
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ bl  callee_low
+ blx callee_low
+ bl  callee_low2
+ blx callee_low2
+ bl  callee_high
+ blx callee_high
+ bl  callee_high2
+ blx callee_high2
+ bl  blx_far
+ blx blx_far2
+// blx to ARM instruction should be written as a BL
+ bl  callee_arm_low
+ blx callee_arm_low
+ bl  callee_arm_high
+ blx callee_arm_high
+ bx lr
+
+ .section .callee_high, "ax",%progbits
+ .balign 0x100
+ .thumb
+ .type callee_high,%function
+callee_high:
+ bx lr
+ .type callee_high2,%function
+callee_high2:
+ bx lr
+
+ .section .callee_arm_high, "ax",%progbits
+ .arm
+ .balign 0x100
+ .type callee_arm_high,%function
+callee_arm_high:
+  bx lr
+
+// CHECK-THUMB: Disassembly of section .callee1:
+// CHECK-THUMB-NEXT: callee_low:
+// CHECK-THUMB-NEXT:    b4:       70 47   bx      lr
+// CHECK-THUMB: callee_low2:
+// CHECK-THUMB-NEXT:    b6:       70 47   bx      lr
+
+// CHECK-ARM: Disassembly of section .callee2:
+// CHECK-ARM-NEXT: callee_arm_low:
+// CHECK-ARM-NEXT:    100:        1e ff 2f e1     bx      lr
+
+// CHECK-ARM: Disassembly of section .caller:
+// CHECK-ARM-NEXT: _start:
+// CHECK-ARM-NEXT:   10000:       2b c0 ff fa     blx     #-65364 <callee_low>
+// CHECK-ARM-NEXT:   10004:       2a c0 ff fa     blx     #-65368 <callee_low>
+// CHECK-ARM-NEXT:   10008:       29 c0 ff fb     blx     #-65370 <callee_low2>
+// CHECK-ARM-NEXT:   1000c:       28 c0 ff fb     blx     #-65374 <callee_low2>
+// CHECK-ARM-NEXT:   10010:       3a 00 00 fa     blx     #232 <callee_high>
+// CHECK-ARM-NEXT:   10014:       39 00 00 fa     blx     #228 <callee_high>
+// CHECK-ARM-NEXT:   10018:       38 00 00 fb     blx     #226 <callee_high2>
+// CHECK-ARM-NEXT:   1001c:       37 00 00 fb     blx     #222 <callee_high2>
+// 10020 + 1FFFFFC + 8 = 0x2010024 = blx_far
+// CHECK-ARM-NEXT:   10020:       ff ff 7f fa     blx     #33554428
+// 10024 + 1FFFFFC + 8 = 0x2010028 = blx_far2
+// CHECK-ARM-NEXT:   10024:       ff ff 7f fa     blx     #33554428
+// CHECK-ARM-NEXT:   10028:       34 c0 ff eb     bl      #-65328 <callee_arm_low>
+// CHECK-ARM-NEXT:   1002c:       33 c0 ff eb     bl      #-65332 <callee_arm_low>
+// CHECK-ARM-NEXT:   10030:       72 00 00 eb     bl      #456 <callee_arm_high>
+// CHECK-ARM-NEXT:   10034:       71 00 00 eb     bl      #452 <callee_arm_high>
+// CHECK-ARM-NEXT:   10038:       1e ff 2f e1     bx      lr
+
+// CHECK-THUMB: Disassembly of section .callee3:
+// CHECK-THUMB: callee_high:
+// CHECK-THUMB-NEXT:    10100:       70 47   bx      lr
+// CHECK-THUMB: callee_high2:
+// CHECK-THUMB-NEXT:    10102:       70 47   bx      lr
+
+// CHECK-ARM: Disassembly of section .callee4:
+// CHECK-NEXT-ARM: callee_arm_high:
+// CHECK-NEXT-ARM:   10200:     1e ff 2f e1     bx      lr

Propchange: lld/trunk/test/ELF/arm-blx.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-blx.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Modified: lld/trunk/test/ELF/arm-mov-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-mov-relocs.s?rev=272881&r1=272880&r2=272881&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-mov-relocs.s (original)
+++ lld/trunk/test/ELF/arm-mov-relocs.s Thu Jun 16 04:53:46 2016
@@ -1,9 +1,13 @@
 // RUN: llvm-mc -filetype=obj -triple=armv7a-unknown-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2
 // RUN: llvm-objdump -d %t2 -triple=armv7a-unknown-linux-gnueabi | FileCheck %s
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-unknown-linux-gnueabi %s -o %t3
+// RUN: ld.lld %t3 -o %t4
+// RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi | FileCheck %s
 // REQUIRES: arm
 
-// Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations
+// Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as
+// the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations.
  .syntax unified
  .globl _start
 _start:

Added: lld/trunk/test/ELF/arm-thumb-blx.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-blx.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-blx.s (added)
+++ lld/trunk/test/ELF/arm-thumb-blx.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/arm-thumb-blx-targets.s -o %ttarget
+// RUN: echo "SECTIONS { \
+// RUN:          .R_ARM_CALL24_callee1 : { *(.R_ARM_CALL24_callee_low) } \
+// RUN:          .R_ARM_CALL24_callee2 : { *(.R_ARM_CALL24_callee_thumb_low) } \
+// RUN:          .caller : { *(.text) } \
+// RUN:          .R_ARM_CALL24_callee3 : { *(.R_ARM_CALL24_callee_high) } \
+// RUN:          .R_ARM_CALL24_callee4 : { *(.R_ARM_CALL24_callee_thumb_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %ttarget -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s 
+// REQUIRES: arm
+// Test BLX instruction is chosen for Thumb BL/BLX instruction and ARM callee
+// 2 byte nops are used to test the pc-rounding behaviour. As a BLX from a
+// 2 byte aligned destination is defined as Align(PC,4) + immediate:00
+// FIXME: llvm-mc has problems assembling BLX unless the destination is
+// external. The targets of the BL and BLX instructions are in arm-thumb-blx-target.s
+ .syntax unified
+ .section .text, "ax",%progbits
+ .thumb
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ blx  callee_low
+ nop
+ bl callee_low
+ nop
+ blx  callee_high
+ nop
+ bl callee_high
+ nop
+ blx  blx_far
+ nop
+ bl   blx_far
+ nop
+// Expect BLX to thumb target to be written out as a BL
+ blx   callee_thumb_low
+ nop
+ blx   callee_thumb_high
+ bx lr
+
+// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee1:
+// CHECK-NEXT-ARM: callee_low:
+// CHECK-NEXT-ARM:      b4:     1e ff 2f e1     bx      lr
+
+// CHECK-THUMB: Disassembly of section .R_ARM_CALL24_callee2:
+// CHECK-NEXT-THUMB: callee_thumb_low:
+// CHECK-NEXT-THUMB:     100:	70 47 	bx	lr
+
+// CHECK-THUMB: Disassembly of section .caller:
+// CHECK-THUMB: _start:
+// Align(0x10000,4) - 0xff50 (65360) + 4 = 0xb4 = callee_low
+// CHECK-NEXT-THUMB:   10000:       f0 f7 58 e8     blx     #-65360
+// CHECK-NEXT-THUMB:   10004:       00 bf   nop
+// Align(0x10006,4) - 0xff54 (65364) + 4 = 0xb4 = callee_low
+// CHECK-NEXT-THUMB:   10006:       f0 f7 56 e8     blx     #-65364
+// CHECK-NEXT-THUMB:   1000a:       00 bf   nop
+// Align(0x1000c,4) + 0xf0 (240) + 4 = 0x10100 = callee_high
+// CHECK-NEXT-THUMB:   1000c:   00 f0 78 e8     blx     #240
+// CHECK-NEXT-THUMB:   10010:       00 bf   nop
+// Align(0x10012,4) + 0xec (236) + 4 = 0x10100 = callee_high
+// CHECK-NEXT-THUMB:   10012:       00 f0 76 e8     blx     #236
+// CHECK-NEXT-THUMB:   10016:       00 bf   nop
+// Align(0x10018,4) + 0xfffffc (16777212) = 0x1010018 = blx_far
+// CHECK-NEXT-THUMB:   10018:       ff f3 fe c7     blx     #16777212
+// CHECK-NEXT-THUMB:   1001c:       00 bf   nop
+// Align(0x1001e,4) + 0xfffff8 (16777208) = 0x1010018 = blx_far
+// CHECK-NEXT-THUMB:   1001e:       ff f3 fc c7     blx     #16777208
+// CHECK-NEXT-THUMB:   10022:       00 bf   nop
+// 10024 - 0xff28 (65320) + 4 = 0x100 = callee_thumb_low
+// CHECK-NEXT-THUMB:   10024:       f0 f7 6c f8     bl      #-65320
+// CHECK-NEXT-THUMB:   10028:       00 bf   nop
+// 1002a + 0x1d2 (466) + 4 = 0x10200 = callee_thumb_high
+// CHECK-NEXT-THUMB:   1002a:       00 f0 e9 f8     bl      #466
+// CHECK-NEXT-THUMB:   1002e:       70 47   bx      lr
+
+
+// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee3:
+// CHECK-NEXT-ARM: callee_high:
+// CHECK-NEXT-ARM:   10100:     1e ff 2f e1     bx      lr
+
+// CHECK: Disassembly of section .R_ARM_CALL24_callee4:
+// CHECK-NEXT-THUMB:callee_thumb_high:
+// CHECK-NEXT-THUMB:   10200:   70 47   bx      lr

Propchange: lld/trunk/test/ELF/arm-thumb-blx.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-thumb-blx.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/arm-thumb-branch-error.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-branch-error.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-branch-error.s (added)
+++ lld/trunk/test/ELF/arm-thumb-branch-error.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,19 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: not ld.lld  %t %tfar -o %t2 2>&1 | FileCheck %s
+// REQUIRES: arm
+ .syntax unified
+ .section .text, "ax",%progbits
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ // address of too_far symbols are just out of range of ARM branch with
+ // 26-bit immediate field and an addend of -8
+ bl  too_far1
+ b   too_far2
+ beq.w too_far3
+
+// CHECK: R_ARM_THM_CALL out of range
+// CHECK-NEXT: R_ARM_THM_JUMP24 out of range
+// CHECK-NEXT: R_ARM_THM_JUMP19 out of range

Propchange: lld/trunk/test/ELF/arm-thumb-branch-error.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-thumb-branch-error.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/arm-thumb-branch.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-branch.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-branch.s (added)
+++ lld/trunk/test/ELF/arm-thumb-branch.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,59 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: echo "SECTIONS { \
+// RUN:          .callee1 : { *(.callee_low) } \
+// RUN:          .caller : { *(.text) } \
+// RUN:          .callee2 : { *(.callee_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck  %s
+// REQUIRES: arm
+
+ .syntax unified
+ .thumb
+ .section .callee_low, "ax",%progbits
+ .align 2
+ .type callee_low,%function
+callee_low:
+ bx lr
+
+ .section .text, "ax",%progbits
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ bl  callee_low
+ b   callee_low
+ beq callee_low
+ bl  callee_high
+ b   callee_high
+ bne callee_high
+ bl  far_uncond
+ b   far_uncond
+ bgt far_cond
+ bx lr
+
+ .section .callee_high, "ax",%progbits
+ .align 2
+ .type callee_high,%function
+callee_high:
+ bx lr
+
+// CHECK: Disassembly of section .callee1:
+// CHECK-NEXT: callee_low:
+// CHECK-NEXT:      b4:       70 47   bx      lr
+// CHECK-NEXT: Disassembly of section .caller:
+// CHECK-NEXT: _start:
+// CHECK-NEXT:   10000:       f0 f7 58 f8     bl      #-65360
+// CHECK-NEXT:   10004:       f0 f7 56 b8     b.w     #-65364
+// CHECK-NEXT:   10008:       30 f4 54 a8     beq.w   #-65368
+// CHECK-NEXT:   1000c:       00 f0 0c f8     bl      #24
+// CHECK-NEXT:   10010:       00 f0 0a b8     b.w     #20
+// CHECK-NEXT:   10014:       40 f0 08 80     bne.w   #16
+// CHECK-NEXT:   10018:       ff f3 ff d7     bl      #16777214
+// CHECK-NEXT:   1001c:       ff f3 fd 97     b.w     #16777210
+// CHECK-NEXT:   10020:       3f f3 ff af     bgt.w   #1048574
+// CHECK-NEXT:   10024:       70 47   bx      lr
+// CHECK-NEXT:   10026:       00 00   movs    r0, r0
+// CHECK-NEXT: Disassembly of section .callee2:
+// CHECK-NEXT: callee_high:
+// CHECK-NEXT:   10028:       70 47   bx      lr

Propchange: lld/trunk/test/ELF/arm-thumb-branch.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-thumb-branch.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s (added)
+++ lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,72 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:          .R_ARM_PC11_1 : { *(.R_ARM_PC11_1) } \
+// RUN:          .caller : { *(.caller) } \
+// RUN:          .R_ARM_PC11_2 : { *(.R_ARM_PC11_2) } \
+// RUN:          .text : { *(.text) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
+// REQUIRES: arm
+
+// Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N
+// the source of these relocations is a binary file arm-thumb-narrow-branch.o
+// which has been assembled with the GNU assembler as llvm-mc doesn't emit it
+// as the range of +-2048 bytes is too small to be practically useful for out
+// of section branches.
+ .syntax unified
+
+.global callee_low_far
+.type callee_low_far,%function
+callee_low_far = 0x809
+
+ .section .R_ARM_PC11_1,"ax",%progbits
+ .thumb
+ .balign 0x1000
+ .type callee_low,%function
+ .globl callee_low
+callee_low:
+ bx lr
+
+ .text
+ .align 2
+ .thumb
+ .globl _start
+ .type _start, %function
+_start:
+ bl callers
+ bx lr
+
+ .section .R_ARM_PC11_2,"ax",%progbits
+ .thumb
+ .align 2
+ .type callee_high,%function
+ .globl callee_high
+callee_high:
+ bx lr
+
+.global callee_high_far
+.type callee_high_far,%function
+callee_high_far = 0x180d
+
+// CHECK: Disassembly of section .R_ARM_PC11_1:
+// CHECK-NEXT: callee_low:
+// CHECK-NEXT:    1000:       70 47   bx      lr
+// CHECK-NEXT: Disassembly of section .caller:
+// CHECK-NEXT: callers:
+// 1004 - 0x800 (2048) + 4 = 0x808 = callee_low_far
+// CHECK-NEXT:    1004:       00 e4   b       #-2048
+// 1006 - 0xa (10) + 4 = 0x1000 = callee_low
+// CHECK-NEXT:    1006:       fb e7   b       #-10
+// 1008 + 4 + 4 = 0x1010 = callee_high
+// CHECK-NEXT:    1008:       02 e0   b       #4
+// 100a + 0x7fe (2046) + 4 = 0x180c = callee_high_far
+// CHECK-NEXT:    100a:       ff e3   b       #2046
+// CHECK-NEXT:    100c:       70 47   bx      lr
+// CHECK-NEXT:    100e:       00 bf   nop
+// CHECK-NEXT: Disassembly of section .R_ARM_PC11_2:
+// CHECK-NEXT: callee_high:
+// CHECK-NEXT:    1010:       70 47   bx      lr
+// CHECK-NEXT: Disassembly of section .text:
+// CHECK-NEXT: _start:
+// CHECK-NEXT:    1014:       ff f7 f6 ff     bl      #-20
+// CHECK-NEXT:    1018:       70 47   bx      lr

Propchange: lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-thumb-narrow-branch-check.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/arm-thumb-plt-reloc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-plt-reloc.s?rev=272881&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-plt-reloc.s (added)
+++ lld/trunk/test/ELF/arm-thumb-plt-reloc.s Thu Jun 16 04:53:46 2016
@@ -0,0 +1,101 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2
+// RUN: ld.lld %t1 %t2 -o %t
+// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t | FileCheck %s
+// RUN: ld.lld -shared %t1 %t2 -o %t3
+// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s
+// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s
+// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
+// REQUIRES: arm
+//
+// Test PLT entry generation
+ .syntax unified
+ .text
+ .align 2
+ .globl _start
+ .type  _start,%function
+_start:
+// FIXME, interworking is only supported for BL via BLX at the moment, when
+// interworking thunks are available for b.w and b<cond>.w this can be altered
+// to test the different forms of interworking.
+ bl func1
+ bl func2
+ bl func3
+
+// Executable, expect no PLT
+// CHECK: Disassembly of section .text:
+// CHECK-NEXT: func1:
+// CHECK-NEXT:   11000: 70 47   bx      lr
+// CHECK: func2:
+// CHECK-NEXT:   11002: 70 47   bx      lr
+// CHECK: func3:
+// CHECK-NEXT:   11004: 70 47   bx      lr
+// CHECK-NEXT:   11006: 00 00   movs    r0, r0
+// CHECK: _start:
+// 11008 + 4 -12 = 0x11000 = func1
+// CHECK-NEXT:   11008: ff f7 fa ff     bl      #-12
+// 1100c + 4 -14 = 0x11002 = func2
+// CHECK-NEXT:   1100c: ff f7 f9 ff     bl      #-14
+// 11010 + 4 -16 = 0x11004 = func3
+// CHECK-NEXT:   11010: ff f7 f8 ff     bl      #-16
+
+// Expect PLT entries as symbols can be preempted
+// .text is Thumb and .plt is ARM, llvm-objdump can currently only disassemble
+// as ARM or Thumb. Work around by disassembling twice.
+// DSOTHUMB: Disassembly of section .text:
+// DSOTHUMB: func1:
+// DSOTHUMB-NEXT:    1000:       70 47   bx      lr
+// DSOTHUMB: func2:
+// DSOTHUMB-NEXT:    1002:       70 47   bx      lr
+// DSOTHUMB: func3:
+// DSOTHUMB-NEXT:    1004:       70 47   bx      lr
+// DSOTHUMB-NEXT:    1006:       00 00   movs    r0, r0
+// DSOTHUMB: _start:
+// 0x1008 + 0x28 + 4 = 0x1034 = PLT func1
+// DSOTHUMB-NEXT:    1008:       00 f0 14 e8     blx     #40
+// 0x100c + 0x34 + 4 = 0x1044 = PLT func2
+// DSOTHUMB-NEXT:    100c:       00 f0 1a e8     blx     #52
+// 0x1010 + 0x40 + 4 = 0x1054 = PLT func3
+// DSOTHUMB-NEXT:    1010:       00 f0 20 e8     blx     #64
+// DSOARM: Disassembly of section .plt:
+// DSOARM: .plt:
+// DSOARM-NEXT:    1020:       04 e0 2d e5     str     lr, [sp, #-4]!
+// DSOARM-NEXT:    1024:       04 e0 9f e5     ldr     lr, [pc, #4]
+// DSOARM-NEXT:    1028:       0e e0 8f e0     add     lr, pc, lr
+// DSOARM-NEXT:    102c:       08 f0 be e5     ldr     pc, [lr, #8]!
+// DSOARM-NEXT:    1030:       d0 1f 00 00
+// 0x1028 + 8 + 1fd0 = 0x3000
+// DSOARM-NEXT:    1034:       04 c0 9f e5     ldr     r12, [pc, #4]
+// DSOARM-NEXT:    1038:       0f c0 8c e0     add     r12, r12, pc
+// DSOARM-NEXT:    103c:       00 f0 9c e5     ldr     pc, [r12]
+// DSOARM-NEXT:    1040:       cc 1f 00 00
+// 0x1038 + 8 + 1fcc = 0x300c
+// DSOARM-NEXT:    1044:       04 c0 9f e5     ldr     r12, [pc, #4]
+// DSOARM-NEXT:    1048:       0f c0 8c e0     add     r12, r12, pc
+// DSOARM-NEXT:    104c:       00 f0 9c e5     ldr     pc, [r12]
+// DSOARM-NEXT:    1050:       c0 1f 00 00
+// 0x1048 + 8 + 1fc0 = 0x3010
+// DSOARM-NEXT:    1054:       04 c0 9f e5     ldr     r12, [pc, #4]
+// DSOARM-NEXT:    1058:       0f c0 8c e0     add     r12, r12, pc
+// DSOARM-NEXT:    105c:       00 f0 9c e5     ldr     pc, [r12]
+// DSOARM-NEXT:    1060:       b4 1f 00 00
+// 0x1058 + 8 + 1fb4 = 0x3014
+
+// DSOREL:    Name: .got.plt
+// DSOREL-NEXT:    Type: SHT_PROGBITS
+// DSOREL-NEXT:    Flags [
+// DSOREL-NEXT:      SHF_ALLOC
+// DSOREL-NEXT:      SHF_WRITE
+// DSOREL-NEXT:    ]
+// DSOREL-NEXT:    Address: 0x3000
+// DSOREL-NEXT:    Offset:
+// DSOREL-NEXT:    Size: 24
+// DSOREL-NEXT:    Link:
+// DSOREL-NEXT:    Info:
+// DSOREL-NEXT:    AddressAlignment: 4
+// DSOREL-NEXT:    EntrySize:
+// DSOREL:  Relocations [
+// DSOREL-NEXT:  Section (4) .rel.plt {
+// DSOREL-NEXT:    0x300C R_ARM_JUMP_SLOT func1 0x0
+// DSOREL-NEXT:    0x3010 R_ARM_JUMP_SLOT func2 0x0
+// DSOREL-NEXT:    0x3014 R_ARM_JUMP_SLOT func3 0x0

Propchange: lld/trunk/test/ELF/arm-thumb-plt-reloc.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-thumb-plt-reloc.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id




More information about the llvm-commits mailing list