[lld] 6f9ff1b - [lld][ARM] support position independent thunks for Armv4(T)

Ties Stuij via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 13 03:57:16 PST 2023


Author: Ties Stuij
Date: 2023-01-13T11:54:41Z
New Revision: 6f9ff1beee9d12aca0c9caa9ae0051dc6d0a718c

URL: https://github.com/llvm/llvm-project/commit/6f9ff1beee9d12aca0c9caa9ae0051dc6d0a718c
DIFF: https://github.com/llvm/llvm-project/commit/6f9ff1beee9d12aca0c9caa9ae0051dc6d0a718c.diff

LOG: [lld][ARM] support position independent thunks for Armv4(T)

- Position independent thunks now work for both Armv4 and Armv4T
- Armv4 arm->arm thunks don't emit a BX anymore, which doesn't exist for the
  arch. This fixes https://github.com/llvm/llvm-project/issues/50764.
- Armv4 and Armv4T both have the same arm->arm behaviour. Which also is
  desirable for the above ticket.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D141272

Added: 
    lld/test/ELF/arm-bl-v4.s

Modified: 
    lld/ELF/Thunks.cpp
    lld/test/ELF/arm-bl-v4t.s
    lld/test/ELF/arm-bx-v4t.s
    lld/test/ELF/arm-thumb-interwork-thunk-v5.s
    lld/test/ELF/arm-thunk-multipass-plt.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 52c0ffc28ab1..5964196a1bae 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -199,17 +199,46 @@ class ARMV5LongLdrPcThunk final : public ARMThunk {
   void addSymbols(ThunkSection &isec) override;
 };
 
+// Implementations of Thunks for v4. BLX is not supported, and loads
+// will not invoke Arm/Thumb state changes.
+class ARMV4PILongBXThunk final : public ARMThunk {
+public:
+  ARMV4PILongBXThunk(Symbol &dest, int64_t addend) : ARMThunk(dest, addend) {}
+
+  uint32_t sizeLong() override { return 16; }
+  void writeLong(uint8_t *buf) override;
+  void addSymbols(ThunkSection &isec) override;
+};
+
 class ARMV4PILongThunk final : public ARMThunk {
 public:
   ARMV4PILongThunk(Symbol &dest, int64_t addend) : ARMThunk(dest, addend) {}
 
+  uint32_t sizeLong() override { return 12; }
+  void writeLong(uint8_t *buf) override;
+  void addSymbols(ThunkSection &isec) override;
+};
+
+class ThumbV4PILongBXThunk final : public ThumbThunk {
+public:
+  ThumbV4PILongBXThunk(Symbol &dest, int64_t addend)
+      : ThumbThunk(dest, addend) {}
+
   uint32_t sizeLong() override { return 16; }
   void writeLong(uint8_t *buf) override;
   void addSymbols(ThunkSection &isec) override;
 };
 
-// Implementations of Thunks for v4. BLX is not supported, and loads
-// will not invoke Arm/Thumb state changes.
+class ThumbV4PILongThunk final : public ThumbThunk {
+public:
+  ThumbV4PILongThunk(Symbol &dest, int64_t addend)
+      : ThumbThunk(dest, addend) {}
+
+  uint32_t sizeLong() override { return 20; }
+  void writeLong(uint8_t *buf) override;
+  void addSymbols(ThunkSection &isec) override;
+};
+
 class ARMV4ABSLongBXThunk final : public ARMThunk {
 public:
   ARMV4ABSLongBXThunk(Symbol &dest, int64_t addend) : ARMThunk(dest, addend) {}
@@ -788,7 +817,7 @@ void ThumbV4ABSLongThunk::addSymbols(ThunkSection &isec) {
   addSymbol("$d", STT_NOTYPE, 12, isec);
 }
 
-void ARMV4PILongThunk::writeLong(uint8_t *buf) {
+void ARMV4PILongBXThunk::writeLong(uint8_t *buf) {
   const uint8_t data[] = {
       0x04, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc,#4] ; L2
       0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
@@ -801,13 +830,77 @@ void ARMV4PILongThunk::writeLong(uint8_t *buf) {
   target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 12);
 }
 
+void ARMV4PILongBXThunk::addSymbols(ThunkSection &isec) {
+  addSymbol(saver().save("__ARMv4PILongBXThunk_" + destination.getName()),
+            STT_FUNC, 0, isec);
+  addSymbol("$a", STT_NOTYPE, 0, isec);
+  addSymbol("$d", STT_NOTYPE, 12, isec);
+}
+
+void ARMV4PILongThunk::writeLong(uint8_t *buf) {
+  const uint8_t data[] = {
+      0x00, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc] ; L2
+      0x0c, 0xf0, 0x8f, 0xe0, // L1: add pc, pc, r12
+      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
+  };
+  uint64_t s = getARMThunkDestVA(destination);
+  uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+  memcpy(buf, data, sizeof(data));
+  target->relocateNoSym(buf + 8, R_ARM_REL32, s - p - 12);
+}
+
 void ARMV4PILongThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__ARMv4PILongThunk_" + destination.getName()),
             STT_FUNC, 0, isec);
   addSymbol("$a", STT_NOTYPE, 0, isec);
+  addSymbol("$d", STT_NOTYPE, 8, isec);
+}
+
+void ThumbV4PILongBXThunk::writeLong(uint8_t *buf) {
+  const uint8_t data[] = {
+      0x78, 0x47,             // P:  bx pc
+      0xfd, 0xe7,             //     b #-6 ; Arm recommended sequence to follow bx pc
+      0x00, 0xc0, 0x9f, 0xe5, //     ldr r12, [pc] ; L2
+      0x0f, 0xf0, 0x8c, 0xe0, // L1: add pc, r12, pc
+      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
+  };
+  uint64_t s = getARMThunkDestVA(destination);
+  uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+  memcpy(buf, data, sizeof(data));
+  target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 16);
+}
+
+void ThumbV4PILongBXThunk::addSymbols(ThunkSection &isec) {
+  addSymbol(saver().save("__Thumbv4PILongBXThunk_" + destination.getName()),
+            STT_FUNC, 1, isec);
+  addSymbol("$t", STT_NOTYPE, 0, isec);
+  addSymbol("$a", STT_NOTYPE, 4, isec);
   addSymbol("$d", STT_NOTYPE, 12, isec);
 }
 
+void ThumbV4PILongThunk::writeLong(uint8_t *buf) {
+  const uint8_t data[] = {
+      0x78, 0x47,             // P:  bx pc
+      0xfd, 0xe7,             //     b #-6 ; Arm recommended sequence to follow bx pc
+      0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, [pc,#4] ; L2
+      0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
+      0x1c, 0xff, 0x2f, 0xe1, //     bx ip
+      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
+  };
+  uint64_t s = getARMThunkDestVA(destination);
+  uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+  memcpy(buf, data, sizeof(data));
+  target->relocateNoSym(buf + 16, R_ARM_REL32, s - p - 16);
+}
+
+void ThumbV4PILongThunk::addSymbols(ThunkSection &isec) {
+  addSymbol(saver().save("__Thumbv4PILongThunk_" + destination.getName()),
+            STT_FUNC, 1, isec);
+  addSymbol("$t", STT_NOTYPE, 0, isec);
+  addSymbol("$a", STT_NOTYPE, 4, isec);
+  addSymbol("$d", STT_NOTYPE, 16, isec);
+}
+
 // Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
 void MipsThunk::writeTo(uint8_t *buf) {
   uint64_t s = destination.getVA();
@@ -1143,8 +1236,6 @@ static Thunk *addThunkAArch64(RelType type, Symbol &s, int64_t a) {
 // - MOVT and MOVW instructions cannot be used.
 // - We can't rewrite BL in place to BLX. We will need thunks.
 //
-// TODO: Support PIC interworking thunks for V4T.
-// TODO: More efficient PIC non-interworking thunks for V4T.
 // TODO: use B for short Thumb->Arm thunks instead of LDR (this doesn't work for
 //       Arm->Thumb, as in Arm state no BX PC trick; it doesn't switch state).
 static Thunk *addThunkArmv4(RelType reloc, Symbol &s, int64_t a) {
@@ -1155,17 +1246,20 @@ static Thunk *addThunkArmv4(RelType reloc, Symbol &s, int64_t a) {
   case R_ARM_PLT32:
   case R_ARM_JUMP24:
   case R_ARM_CALL:
-    if (config->picThunk)
-      // can be used for both Arm->Arm and Arm->Thumb
+    if (config->picThunk) {
+      if (thumb_target)
+        return make<ARMV4PILongBXThunk>(s, a);
       return make<ARMV4PILongThunk>(s, a);
+    }
     if (thumb_target)
       return make<ARMV4ABSLongBXThunk>(s, a);
     return make<ARMV5LongLdrPcThunk>(s, a);
   case R_ARM_THM_CALL:
-    if (config->picThunk && !thumb_target)
-      fatal("PIC relocations across state change not supported for Armv4T");
-    if (config->picThunk && thumb_target)
-      return make<ThumbV6MPILongThunk>(s, a);
+    if (config->picThunk) {
+      if (thumb_target)
+        return make<ThumbV4PILongThunk>(s, a);
+      return make<ThumbV4PILongBXThunk>(s, a);
+    }
     if (thumb_target)
       return make<ThumbV4ABSLongThunk>(s, a);
     return make<ThumbV4ABSLongBXThunk>(s, a);
@@ -1187,7 +1281,7 @@ static Thunk *addThunkArmv5v6(RelType reloc, Symbol &s, int64_t a) {
   case R_ARM_CALL:
   case R_ARM_THM_CALL:
     if (config->picThunk)
-      return make<ARMV4PILongThunk>(s, a);
+      return make<ARMV4PILongBXThunk>(s, a);
     return make<ARMV5LongLdrPcThunk>(s, a);
   }
   fatal("relocation " + toString(reloc) + " to " + toString(s) +

diff  --git a/lld/test/ELF/arm-bl-v4.s b/lld/test/ELF/arm-bl-v4.s
new file mode 100644
index 000000000000..8be4dcacd74c
--- /dev/null
+++ b/lld/test/ELF/arm-bl-v4.s
@@ -0,0 +1,82 @@
+// REQUIRES: arm
+// RUN: rm -rf %t && split-file %s %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv4-none-linux-gnueabi %t/a.s -o %t/a.o
+// RUN: ld.lld %t/a.o --script %t/far.lds -o %t/a-far
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4-none-linux-gnueabi %t/a-far | FileCheck %s --check-prefixes=FAR
+// RUN: ld.lld %t/a.o --script %t/near.lds -o %t/a-near
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4-none-linux-gnueabi %t/a-near | FileCheck %s --check-prefixes=NEAR
+// RUN: ld.lld %t/a.o -pie --script %t/far.lds -o %t/a-far-pie
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4-none-linux-gnueabi %t/a-far-pie | FileCheck %s --check-prefixes=FAR-PIE
+// RUN: ld.lld %t/a.o -pie --script %t/near.lds -o %t/a-near-pie
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4-none-linux-gnueabi %t/a-near-pie | FileCheck %s --check-prefixes=NEAR
+
+/// On Armv4 there is no blx instruction so long branch/exchange looks slightly
+/// 
diff erent.
+
+//--- a.s
+ .text
+ .syntax unified
+ .cpu    arm7tdmi
+
+ .section .low, "ax", %progbits
+ .arm
+ .globl _start
+ .type   _start,%function
+ .p2align       2
+_start:
+  bl target
+  mov pc, lr
+
+// FAR-LABEL: <_start>:
+// FAR-NEXT:   1000000:      	bl	0x1000008 <__ARMv5LongLdrPcThunk_target> @ imm = #0
+// FAR-NEXT:                	mov pc, lr
+// FAR-EMPTY:
+// FAR-NEXT:  <__ARMv5LongLdrPcThunk_target>:
+// FAR-NEXT:   1000008:      	ldr	pc, [pc, #-4]           @ 0x100000c <__ARMv5LongLdrPcThunk_target+0x4>
+// FAR-EMPTY:
+// FAR-NEXT:  <$d>:
+// FAR-NEXT:   100000c: 00 00 00 06  	.word	0x06000000
+
+// FAR-PIE-LABEL: <_start>:
+// FAR-PIE-NEXT:   1000000:      	bl	0x1000008 <__ARMv4PILongThunk_target> @ imm = #0
+// FAR-PIE-NEXT:                	mov pc, lr
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <__ARMv4PILongThunk_target>:
+// FAR-PIE-NEXT:   1000008:      	ldr	r12, [pc]               @ 0x1000010 <__ARMv4PILongThunk_target+0x8>
+// FAR-PIE-NEXT:                	add	pc, pc, r12
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$d>:
+// FAR-PIE-NEXT:   1000010: ec ff ff 04  	.word	0x04ffffec
+
+// NEAR-LABEL: <_start>:
+// NEAR-NEXT:  1000000:      	bl 0x1000008 <target> @ imm = #0
+// NEAR-NEXT:               	mov pc, lr
+
+.section .high, "ax", %progbits
+ .arm
+ .globl target
+ .type target,%function
+target:
+  mov pc, lr
+
+// FAR-LABEL: <target>:
+// FAR-NEXT:   6000000:      	mov pc, lr
+
+// FAR-PIE-LABEL: <target>:
+// FAR-PIE-NEXT:   6000000:     mov pc, lr
+                                         
+// NEAR-LABEL: <target>:
+// NEAR-LABEL:  1000008:      	mov pc, lr
+
+//--- far.lds
+SECTIONS {
+  . = SIZEOF_HEADERS;
+  .low 0x01000000 : { *(.low) }
+  .high 0x06000000 : { *(.high) }
+}
+
+//--- near.lds
+SECTIONS {
+  . = SIZEOF_HEADERS;
+  .all 0x01000000 : { *(.low) *(.high) }
+}

diff  --git a/lld/test/ELF/arm-bl-v4t.s b/lld/test/ELF/arm-bl-v4t.s
index 691995029a46..76fd6a2af3e8 100644
--- a/lld/test/ELF/arm-bl-v4t.s
+++ b/lld/test/ELF/arm-bl-v4t.s
@@ -5,6 +5,10 @@
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-far | FileCheck %s --check-prefixes=FAR
 // RUN: ld.lld %t/a.o --script %t/near.lds -o %t/a-near
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-near | FileCheck %s --check-prefixes=NEAR
+// RUN: ld.lld %t/a.o -pie --script %t/far.lds -o %t/a-far-pie
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-far-pie | FileCheck %s --check-prefixes=FAR-PIE
+// RUN: ld.lld %t/a.o -pie --script %t/near.lds -o %t/a-near-pie
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-near-pie | FileCheck %s --check-prefixes=NEAR
 
 /// On Armv4T there is no blx instruction so long branch/exchange looks slightly
 /// 
diff erent.
@@ -57,6 +61,34 @@ thumb_start:
 // FAR-NEXT:  <$d>:
 // FAR-NEXT:   1000024: 05 00 00 06  	.word	0x06000005
 
+// FAR-PIE-LABEL: <_start>:
+// FAR-PIE-NEXT:   1000000:      	bl	0x1000010 <__ARMv4PILongThunk_target> @ imm = #8
+// FAR-PIE-NEXT:                	bx	lr
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <thumb_start>:
+// FAR-PIE-NEXT:   1000008:      	bl	0x100001c <__Thumbv4PILongThunk_thumb_target> @ imm = #16
+// FAR-PIE-NEXT:                	bx	lr
+// FAR-PIE-NEXT:                	bmi	0xffffba                @ imm = #-88
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <__ARMv4PILongThunk_target>:
+// FAR-PIE-NEXT:   1000010:      	ldr	r12, [pc]               @ 0x1000018 <__ARMv4PILongThunk_target+0x8>
+// FAR-PIE-NEXT:                	add	pc, pc, r12
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$d>:
+// FAR-PIE-NEXT:   1000018: e4 ff ff 04  	.word	0x04ffffe4
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <__Thumbv4PILongThunk_thumb_target>:
+// FAR-PIE-NEXT:   100001c:      	bx	pc
+// FAR-PIE-NEXT:                	b	0x100001c <__Thumbv4PILongThunk_thumb_target> @ imm = #-6
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$a>:
+// FAR-PIE-NEXT:   1000020:      	ldr	r12, [pc, #4]           @ 0x100002c <__Thumbv4PILongThunk_thumb_target+0x10>
+// FAR-PIE-NEXT:                	add	r12, pc, r12
+// FAR-PIE-NEXT:                	bx	r12
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$d>:
+// FAR-PIE-NEXT:   100002c: d9 ff ff 04  	.word	0x04ffffd9
+
 // NEAR-LABEL: <_start>:
 // NEAR-NEXT:  1000000:      	bl	0x100000c <thumb_start+0x4> @ imm = #4
 // NEAR-NEXT:               	bx	lr
@@ -84,6 +116,12 @@ thumb_target:
 // FAR-LABEL: <thumb_target>:
 // FAR-NEXT:   6000004:      	bx	lr
 
+// FAR-PIE-LABEL: <target>:
+// FAR-PIE-NEXT:   6000000:     bx	lr
+// FAR-PIE-EMPTY:
+// FAR-PIE-LABEL: <thumb_target>:
+// FAR-PIE-NEXT:   6000004:     bx	lr
+
 // NEAR-LABEL: <target>:
 // NEAR-LABEL:  100000e:      	bx	lr
 // NEAR-EMPTY:

diff  --git a/lld/test/ELF/arm-bx-v4t.s b/lld/test/ELF/arm-bx-v4t.s
index 8fd6e97053e7..cb7cd7de332a 100644
--- a/lld/test/ELF/arm-bx-v4t.s
+++ b/lld/test/ELF/arm-bx-v4t.s
@@ -5,6 +5,10 @@
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-far | FileCheck %s --check-prefixes=FAR
 // RUN: ld.lld %t/a.o --script %t/near.lds -o %t/a-near
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-near | FileCheck %s --check-prefixes=NEAR
+// RUN: ld.lld %t/a.o -pie --script %t/far.lds -o %t/a-far-pie
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-far-pie | FileCheck %s --check-prefixes=FAR-PIE
+// RUN: ld.lld %t/a.o -pie --script %t/near.lds -o %t/a-near-pie
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --triple=armv4t-none-linux-gnueabi %t/a-near-pie | FileCheck %s --check-prefixes=NEAR-PIE
 
 /// On Arm v4t there is no blx instruction so all interworking must go via
 /// a thunk.
@@ -45,6 +49,29 @@ _start:
 // NEAR-NEXT:  <$d>:
 // NEAR-NEXT:  1000010: 15 00 00 01   .word   0x01000015
 
+// FAR-PIE-LABEL: <_start>:
+// FAR-PIE-NEXT:   1000000:    	bl	0x1000008 <__ARMv4PILongBXThunk_target> @ imm = #0
+// FAR-PIE-NEXT:               	bx	lr
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <__ARMv4PILongBXThunk_target>:
+// FAR-PIE-NEXT:   1000008:     ldr	r12, [pc, #4]           @ 0x1000014 <__ARMv4PILongBXThunk_target+0xc>
+// FAR-PIE-NEXT:                add	r12, pc, r12
+// FAR-PIE-NEXT:                bx	r12
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$d>:
+// FAR-PIE-NEXT:   1000014: ed ff ff 04  	.word	0x04ffffed
+
+// NEAR-PIE-LABEL: <_start>:
+// NEAR-PIE-NEXT:   1000000:    bl	0x1000008 <__ARMv4PILongBXThunk_target> @ imm = #0
+// NEAR-PIE-NEXT:               bx	lr
+// NEAR-PIE-EMPTY:
+// NEAR-PIE-NEXT:  <__ARMv4PILongBXThunk_target>:
+// NEAR-PIE-NEXT:   1000008:    ldr	r12, [pc, #4]           @ 0x1000014 <__ARMv4PILongBXThunk_target+0xc>
+// NEAR-PIE-NEXT:               add	r12, pc, r12
+// NEAR-PIE-NEXT:               bx	r12
+// NEAR-PIE-EMPTY:
+// NEAR-PIE-NEXT:  <$d>:
+// NEAR-PIE-NEXT:   1000014: 05 00 00 00  	.word	0x00000005
 
 .section .high, "ax", %progbits
 .thumb
@@ -71,12 +98,12 @@ target:
 
 // NEAR-LABEL: <target>:
 // NEAR-NEXT:   1000014:       bl      0x100001c <__Thumbv4ABSLongBXThunk__start> @ imm = #4
-// NEAR-NEXT:   1000018:       bx      lr
-// NEAR-NEXT:   100001a:       bmi     0xffffc6                @ imm = #-88
+// NEAR-NEXT:                  bx      lr
+// NEAR-NEXT:                  bmi     0xffffc6                @ imm = #-88
 // NEAR-EMPTY:
 // NEAR-NEXT:  <__Thumbv4ABSLongBXThunk__start>:
 // NEAR-NEXT:   100001c:       bx      pc
-// NEAR-NEXT:   100001e:       b       0x100001c <__Thumbv4ABSLongBXThunk__start> @ imm = #-6
+// NEAR-NEXT:                  b       0x100001c <__Thumbv4ABSLongBXThunk__start> @ imm = #-6
 // NEAR-EMPTY:
 // NEAR-NEXT:  <$a>:
 // NEAR-NEXT:   1000020:       ldr     pc, [pc, #-4]           @ 0x1000024 <__Thumbv4ABSLongBXThunk__start+0x8>
@@ -84,6 +111,38 @@ target:
 // NEAR-NEXT:  <$d>:
 // NEAR-NEXT:   1000024: 00 00 00 01   .word   0x01000000
 
+// FAR-PIE-LABEL: <target>:
+// FAR-PIE-NEXT:   6000000:       	bl	0x6000008 <__Thumbv4PILongBXThunk__start> @ imm = #4
+// FAR-PIE-NEXT:                	bx  lr
+// FAR-PIE-NEXT:                	bmi 0x5ffffb2 <__ARMv4PILongBXThunk_target+0x4ffffaa> @ imm = #-88
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <__Thumbv4PILongBXThunk__start>:
+// FAR-PIE-NEXT:   6000008:      	bx	pc
+// FAR-PIE-NEXT:                	b	0x6000008 <__Thumbv4PILongBXThunk__start> @ imm = #-6
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$a>:
+// FAR-PIE-NEXT:   600000c:      	ldr	r12, [pc]               @ 0x6000014 <__Thumbv4PILongBXThunk__start+0xc>
+// FAR-PIE-NEXT:                	add	pc, r12, pc
+// FAR-PIE-EMPTY:
+// FAR-PIE-NEXT:  <$d>:
+// FAR-PIE-NEXT:   6000014: e8 ff ff fa  	.word	0xfaffffe8
+
+// NEAR-PIE-LABEL: <target>:
+// NEAR-PIE-NEXT:   1000018:      	bl	0x1000020 <__Thumbv4PILongBXThunk__start> @ imm = #4
+// NEAR-PIE-NEXT:               	bx	lr
+// NEAR-PIE-NEXT:               	bmi	0xffffca                @ imm = #-88
+// NEAR-PIE-EMPTY:
+// NEAR-PIE-NEXT:  <__Thumbv4PILongBXThunk__start>:
+// NEAR-PIE-NEXT:   1000020:      	bx	pc
+// NEAR-PIE-NEXT:               	b	0x1000020 <__Thumbv4PILongBXThunk__start> @ imm = #-6
+// NEAR-PIE-EMPTY:
+// NEAR-PIE-NEXT:  <$a>:
+// NEAR-PIE-NEXT:   1000024:      	ldr	r12, [pc]               @ 0x100002c <__Thumbv4PILongBXThunk__start+0xc>
+// NEAR-PIE-NEXT:               	add	pc, r12, pc
+// NEAR-PIE-EMPTY:
+// NEAR-PIE-NEXT:  <$d>:
+// NEAR-PIE-NEXT:   100002c: d0 ff ff ff  	.word	0xffffffd0
+
 #--- far.lds
 SECTIONS {
   . = SIZEOF_HEADERS;

diff  --git a/lld/test/ELF/arm-thumb-interwork-thunk-v5.s b/lld/test/ELF/arm-thumb-interwork-thunk-v5.s
index 846bebb62425..cd687b90beb7 100644
--- a/lld/test/ELF/arm-thumb-interwork-thunk-v5.s
+++ b/lld/test/ELF/arm-thumb-interwork-thunk-v5.s
@@ -41,7 +41,7 @@ _start:
 // CHECK-NEXT: 21018: 11 10 02 00     .word   0x00021011
 
 // CHECK-PI: <_start>:
-// CHECK-PI-NEXT: 11000: ea000003        b       0x11014 <__ARMv4PILongThunk_thumb_func>
+// CHECK-PI-NEXT: 11000: ea000003        b       0x11014 <__ARMv4PILongBXThunk_thumb_func>
 // CHECK-PI-NEXT: 11004: fa000001        blx     0x11010 <thumb_func>
 // CHECK-PI-NEXT: 11008: fa000000        blx     0x11010 <thumb_func>
 // CHECK-PI-NEXT: 1100c: e12fff1e        bx      lr
@@ -49,7 +49,7 @@ _start:
 // CHECK-PI: <thumb_func>:
 // CHECK-PI-NEXT: 11010: 4770    bx      lr
 
-// CHECK-PI: <__ARMv4PILongThunk_thumb_func>:
+// CHECK-PI: <__ARMv4PILongBXThunk_thumb_func>:
 // CHECK-PI-NEXT: 11014: e59fc004        ldr     r12, [pc, #4]
 // CHECK-PI-NEXT: 11018: e08fc00c        add     r12, pc, r12
 // CHECK-PI-NEXT: 1101c: e12fff1c        bx      r12

diff  --git a/lld/test/ELF/arm-thunk-multipass-plt.s b/lld/test/ELF/arm-thunk-multipass-plt.s
index 32f7fb0a3aaa..f12b8f88f4d0 100644
--- a/lld/test/ELF/arm-thunk-multipass-plt.s
+++ b/lld/test/ELF/arm-thunk-multipass-plt.s
@@ -42,7 +42,7 @@ needsplt:
         .section .text.07, "ax", %progbits
         .space (1024 * 1024)
 /// 0xd00040 = preemptible at plt
-// CHECK:      0070000c <__ARMv4PILongThunk_preemptible>:
+// CHECK:      0070000c <__ARMv4PILongBXThunk_preemptible>:
 // CHECK-NEXT:   70000c: b       0xd00040
 
         .section .text.08, "ax", %progbits
@@ -52,7 +52,7 @@ needsplt:
         .balign 2
         bl preemptible
         bl preemptible2
-// CHECK-CALL: 80000c: blx     0x70000c <__ARMv4PILongThunk_preemptible>
+// CHECK-CALL: 80000c: blx     0x70000c <__ARMv4PILongBXThunk_preemptible>
         .balign 2
         .globl preemptible
         .type preemptible, %function


        


More information about the llvm-commits mailing list