[lld] c290038 - Revert "[LLD][ELF][ARM] Do not substitute BL/BLX for non STT_FUNC symbols."

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 7 05:56:12 PST 2020


Author: Nico Weber
Date: 2020-02-07T08:55:52-05:00
New Revision: c29003813ab9bd6ea7b6de40ea8f1fe21979f13f

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

LOG: Revert "[LLD][ELF][ARM] Do not substitute BL/BLX for non STT_FUNC symbols."

There are still problems after the fix in
"[ELF][ARM] Fix regression of BL->BLX substitution after D73542"
so let's revert to get trunk back to green while we investigate.
See https://reviews.llvm.org/D73542

This reverts commit 5461fa2b1fcfcfcd8e28e3ac3383d2245d5d90bf.
This reverts commit 0b4a047bfbd11fe1f5abda8da0e2391c1918162a.

Added: 
    

Modified: 
    lld/ELF/Arch/ARM.cpp
    lld/test/ELF/arm-thumb-interwork-notfunc.s
    lld/test/ELF/arm-thumb-interwork-shared.s
    lld/test/ELF/arm-thumb-undefined-weak.s
    lld/test/ELF/arm-undefined-weak.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 447b5d898ac5..7f18effa096f 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -402,15 +402,11 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     checkInt(loc, val, 31, rel);
     write32le(loc, (read32le(loc) & 0x80000000) | (val & ~0x80000000));
     break;
-  case R_ARM_CALL: {
-    // R_ARM_CALL is used for BL and BLX instructions, for symbols of type
-    // STT_FUNC we choose whether to write a BL or BLX depending on the
-    // value of bit 0 of Val. With bit 0 == 1 denoting Thumb. If the symbol is
-    // not of type STT_FUNC then we must preserve the original instruction.
-    // PLT entries are always ARM state so we know we don't need to interwork.
-    bool isBlx = (read32le(loc) & 0xfe000000) == 0xfa000000;
-    bool interwork = rel.sym && rel.sym->isFunc() && rel.expr != R_PLT_PC;
-    if (interwork ? val & 1 : isBlx) {
+  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(loc, val, 26, rel);
       write32le(loc, 0xfa000000 |                    // opcode
@@ -418,11 +414,11 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
                          ((val >> 2) & 0x00ffffff)); // imm24
       break;
     }
-    // BLX (always unconditional) instruction to an ARM Target, select an
-    // unconditional BL.
-    write32le(loc, 0xeb000000 | (read32le(loc) & 0x00ffffff));
+    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
-  }
     LLVM_FALLTHROUGH;
   case R_ARM_JUMP24:
   case R_ARM_PC24:
@@ -447,23 +443,16 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
                   ((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, for symbols of type
-    // STT_FUNC we choose whether to write a BL or BLX depending on the
-    // value of bit 0 of Val. With bit 0 == 0 denoting ARM, if the symbol is
-    // not of type STT_FUNC then we must preserve the original instruction.
-    // PLT entries are always ARM state so we know we need to interwork.
-    bool isBlx = (read16le(loc + 2) & 0x1000) == 0;
-    bool interwork = (rel.sym && rel.sym->isFunc()) || rel.expr == R_PLT_PC;
-    if (interwork ? (val & 1) == 0 : isBlx) {
-      // We are writing a BLX. Ensure BLX destination is 4-byte aligned. As
-      // the BLX instruction may only be two byte aligned. This must be done
-      // before overflow check.
+  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);
-      write16le(loc + 2, read16le(loc + 2) & ~0x1000);
-    } else {
-      write16le(loc + 2, (read16le(loc + 2) & ~0x1000) | 1 << 12);
     }
+    // Bit 12 is 0 for BLX, 1 for BL
+    write16le(loc + 2, (read16le(loc + 2) & ~0x1000) | (val & 1) << 12);
     if (!config->armJ1J2BranchEncoding) {
       // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
       // 
diff erent encoding rules and range due to J1 and J2 always being 1.
@@ -477,7 +466,6 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
                     ((val >> 1) & 0x07ff));    // imm11
       break;
     }
-  }
     // Fall through as rest of encoding is the same as B.W
     LLVM_FALLTHROUGH;
   case R_ARM_THM_JUMP24:

diff  --git a/lld/test/ELF/arm-thumb-interwork-notfunc.s b/lld/test/ELF/arm-thumb-interwork-notfunc.s
index 49a55f20d401..4f29fdf541fb 100644
--- a/lld/test/ELF/arm-thumb-interwork-notfunc.s
+++ b/lld/test/ELF/arm-thumb-interwork-notfunc.s
@@ -23,9 +23,7 @@ thumb_func_with_explicit_notype:
 /// All the symbols that are targets of the branch relocations do not have
 /// type STT_FUNC. LLD should not insert interworking thunks as non STT_FUNC
 /// symbols have no state information, the ABI assumes the user has manually
-/// done the interworking. For the BL and BLX instructions LLD should
-/// preserve the original instruction instead of writing out the correct one
-/// for the assumed state at the target.
+/// done the interworking.
 .section .arm_caller, "ax", %progbits
 .balign 4
 .arm
@@ -37,24 +35,10 @@ _start:
  b .thumb_target
  b thumb_func_with_notype
  b thumb_func_with_explicit_notype
- bl .arm_target
- bl arm_func_with_notype
- bl arm_func_with_explicit_notype
- bl .thumb_target
- bl thumb_func_with_notype
- bl thumb_func_with_explicit_notype
- blx .arm_target
- blx arm_func_with_notype
- blx arm_func_with_explicit_notype
- blx .thumb_target
- blx thumb_func_with_notype
- blx thumb_func_with_explicit_notype
 
  .section .thumb_caller, "ax", %progbits
  .thumb
  .balign 4
- .global thumb_caller
-thumb_caller:
  b.w .arm_target
  b.w arm_func_with_notype
  b.w arm_func_with_explicit_notype
@@ -67,18 +51,6 @@ thumb_caller:
  beq.w .thumb_target
  beq.w thumb_func_with_notype
  beq.w thumb_func_with_explicit_notype
- bl .arm_target
- bl arm_func_with_notype
- bl arm_func_with_explicit_notype
- bl .thumb_target
- bl thumb_func_with_notype
- bl thumb_func_with_explicit_notype
- blx .arm_target
- blx arm_func_with_notype
- blx arm_func_with_explicit_notype
- blx .thumb_target
- blx thumb_func_with_notype
- blx thumb_func_with_explicit_notype
 
 // CHECK: 00012008 _start:
 // CHECK-NEXT: 12008: b       #-16
@@ -87,41 +59,15 @@ thumb_caller:
 // CHECK-NEXT: 12014: b       #-24
 // CHECK-NEXT: 12018: b       #-28
 // CHECK-NEXT: 1201c: b       #-32
-// CHECK-NEXT: 12020: bl      #-40
-// CHECK-NEXT: 12024: bl      #-44
-// CHECK-NEXT: 12028: bl      #-48
-// CHECK-NEXT: 1202c: bl      #-48
-// CHECK-NEXT: 12030: bl      #-52
-// CHECK-NEXT: 12034: bl      #-56
-// CHECK-NEXT: 12038: blx     #-64
-// CHECK-NEXT: 1203c: blx     #-68
-// CHECK-NEXT: 12040: blx     #-72
-// CHECK-NEXT: 12044: blx     #-72
-// CHECK-NEXT: 12048: blx     #-76
-// CHECK-NEXT: 1204c: blx     #-80
-
-// CHECK: 00012050 thumb_caller:
-// CHECK-NEXT: 12050: b.w     #-84
-// CHECK-NEXT: 12054: b.w     #-88
-// CHECK-NEXT: 12058: b.w     #-92
-// CHECK-NEXT: 1205c: b.w     #-92
-// CHECK-NEXT: 12060: b.w     #-96
-// CHECK-NEXT: 12064: b.w     #-100
-// CHECK-NEXT: 12068: beq.w   #-108
-// CHECK-NEXT: 1206c: beq.w   #-112
-// CHECK-NEXT: 12070: beq.w   #-116
-// CHECK-NEXT: 12074: beq.w   #-116
-// CHECK-NEXT: 12078: beq.w   #-120
-// CHECK-NEXT: 1207c: beq.w   #-124
-// CHECK-NEXT: 12080: bl      #-132
-// CHECK-NEXT: 12084: bl      #-136
-// CHECK-NEXT: 12088: bl      #-140
-// CHECK-NEXT: 1208c: bl      #-140
-// CHECK-NEXT: 12090: bl      #-144
-// CHECK-NEXT: 12094: bl      #-148
-// CHECK-NEXT: 12098: blx     #-156
-// CHECK-NEXT: 1209c: blx     #-160
-// CHECK-NEXT: 120a0: blx     #-164
-// CHECK-NEXT: 120a4: blx     #-164
-// CHECK-NEXT: 120a8: blx     #-168
-// CHECK-NEXT: 120ac: blx     #-172
+// CHECK:      12020: b.w     #-36
+// CHECK-NEXT: 12024: b.w     #-40
+// CHECK-NEXT: 12028: b.w     #-44
+// CHECK-NEXT: 1202c: b.w     #-44
+// CHECK-NEXT: 12030: b.w     #-48
+// CHECK-NEXT: 12034: b.w     #-52
+// CHECK-NEXT: 12038: beq.w   #-60
+// CHECK-NEXT: 1203c: beq.w   #-64
+// CHECK-NEXT: 12040: beq.w   #-68
+// CHECK-NEXT: 12044: beq.w   #-68
+// CHECK-NEXT: 12048: beq.w   #-72
+// CHECK-NEXT: 1204c: beq.w   #-76

diff  --git a/lld/test/ELF/arm-thumb-interwork-shared.s b/lld/test/ELF/arm-thumb-interwork-shared.s
index e8464eb591c4..0b699bdc4532 100644
--- a/lld/test/ELF/arm-thumb-interwork-shared.s
+++ b/lld/test/ELF/arm-thumb-interwork-shared.s
@@ -1,7 +1,7 @@
 // REQUIRES: arm
 // RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t --shared -o %t.so
-// RUN: llvm-objdump -d --no-show-raw-insn -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
  .syntax unified
  .global sym1
  .global elsewhere
@@ -10,51 +10,46 @@ sym1:
  b.w elsewhere
  b.w weakref
 
- bl elsewhere
- bl weakref
-
 // Check that we generate a thunk for an undefined symbol called via a plt
 // entry.
 
 // CHECK: Disassembly of section .text:
 // CHECK-EMPTY:
 // CHECK-NEXT: sym1:
-// CHECK-NEXT:     11e0: b.w #12 <__ThumbV7PILongThunk_elsewhere>
-// CHECK-NEXT:           b.w #20 <__ThumbV7PILongThunk_weakref>
-// CHECK-NEXT:           blx #68
-// CHECK-NEXT:           blx #80
+// CHECK-NEXT: 11e0: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere>
+// CHECK-NEXT: 11e4: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref>
 // CHECK: __ThumbV7PILongThunk_elsewhere:
-// CHECK-NEXT:     11f0: movw    r12, #52
-// CHECK-NEXT:           movt    r12, #0
-// CHECK-NEXT:           add     r12, pc
-// CHECK-NEXT:           bx      r12
+// CHECK-NEXT:     11e8:       40 f2 2c 0c     movw    r12, #44
+// CHECK-NEXT:     11ec:       c0 f2 00 0c     movt    r12, #0
+// CHECK-NEXT:     11f0:       fc 44   add     r12, pc
+// CHECK-NEXT:     11f2:       60 47   bx      r12
 // CHECK: __ThumbV7PILongThunk_weakref:
-// CHECK-NEXT:     11fc: movw    r12, #56
-// CHECK-NEXT:           movt    r12, #0
-// CHECK-NEXT:           add     r12, pc
-// CHECK-NEXT:           bx      r12
+// CHECK-NEXT:     11f4:       40 f2 30 0c     movw    r12, #48
+// CHECK-NEXT:     11f8:       c0 f2 00 0c     movt    r12, #0
+// CHECK-NEXT:     11fc:       fc 44   add     r12, pc
+// CHECK-NEXT:     11fe:       60 47   bx      r12
 
 // CHECK: Disassembly of section .plt:
 // CHECK-EMPTY:
 // CHECK-NEXT: $a:
-// CHECK-NEXT:     1210: str     lr, [sp, #-4]!
-// CHECK-NEXT:           add     lr, pc, #0, #12
-// CHECK-NEXT:           add     lr, lr, #8192
-// CHECK-NEXT:           ldr     pc, [lr, #148]!
+// CHECK-NEXT:     1200:  04 e0 2d e5     str     lr, [sp, #-4]!
+// CHECK-NEXT:     1204:  00 e6 8f e2     add     lr, pc, #0, #12
+// CHECK-NEXT:     1208:  02 ea 8e e2     add     lr, lr, #8192
+// CHECK-NEXT:     120c:  94 f0 be e5     ldr     pc, [lr, #148]!
 // CHECK: $d:
-// CHECK-NEXT:     1220: d4 d4 d4 d4 .word   0xd4d4d4d4
-// CHECK-NEXT:           .word   0xd4d4d4d4
-// CHECK-NEXT:           .word   0xd4d4d4d4
-// CHECK-NEXT:           .word   0xd4d4d4d4
+// CHECK-NEXT:     1210:  d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-NEXT:     1214:  d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-NEXT:     1218:  d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-NEXT:     121c:  d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECK: $a:
-// CHECK-NEXT:     1230: add     r12, pc, #0, #12
-// CHECK-NEXT:           add     r12, r12, #8192
-// CHECK-NEXT:           ldr     pc, [r12, #124]!
+// CHECK-NEXT:     1220:  00 c6 8f e2     add     r12, pc, #0, #12
+// CHECK-NEXT:     1224:  02 ca 8c e2     add     r12, r12, #8192
+// CHECK-NEXT:     1228:  7c f0 bc e5     ldr     pc, [r12, #124]!
 // CHECK: $d:
-// CHECK-NEXT:     123c: d4 d4 d4 d4 .word   0xd4d4d4d4
+// CHECK-NEXT:     122c:  d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECK: $a:
-// CHECK-NEXT:     1240: add     r12, pc, #0, #12
-// CHECK-NEXT:           add     r12, r12, #8192
-// CHECK-NEXT:           ldr     pc, [r12, #112]!
+// CHECK-NEXT:     1230:  00 c6 8f e2     add     r12, pc, #0, #12
+// CHECK-NEXT:     1234:  02 ca 8c e2     add     r12, r12, #8192
+// CHECK-NEXT:     1238:  70 f0 bc e5     ldr     pc, [r12, #112]!
 // CHECK: $d:
-// CHECK-NEXT:     124c: d4 d4 d4 d4 .word   0xd4d4d4d4
+// CHECK-NEXT:     123c:  d4 d4 d4 d4     .word   0xd4d4d4d4

diff  --git a/lld/test/ELF/arm-thumb-undefined-weak.s b/lld/test/ELF/arm-thumb-undefined-weak.s
index 82069a7d9db5..b6812b8cc91a 100644
--- a/lld/test/ELF/arm-thumb-undefined-weak.s
+++ b/lld/test/ELF/arm-thumb-undefined-weak.s
@@ -10,7 +10,6 @@
  .syntax unified
 
  .weak target
- .type target, %function
 
  .text
  .global _start

diff  --git a/lld/test/ELF/arm-undefined-weak.s b/lld/test/ELF/arm-undefined-weak.s
index c7e3f5f7694d..2d4726358095 100644
--- a/lld/test/ELF/arm-undefined-weak.s
+++ b/lld/test/ELF/arm-undefined-weak.s
@@ -12,7 +12,6 @@
  .syntax unified
 
  .weak target
- .type target, %function
 
  .text
  .global _start


        


More information about the llvm-commits mailing list