Skip to content

Commit c290038

Browse files
committed
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 5461fa2. This reverts commit 0b4a047.
1 parent 441cafb commit c290038

File tree

5 files changed

+57
-130
lines changed

5 files changed

+57
-130
lines changed

lld/ELF/Arch/ARM.cpp

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -402,27 +402,23 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
402402
checkInt(loc, val, 31, rel);
403403
write32le(loc, (read32le(loc) & 0x80000000) | (val & ~0x80000000));
404404
break;
405-
case R_ARM_CALL: {
406-
// R_ARM_CALL is used for BL and BLX instructions, for symbols of type
407-
// STT_FUNC we choose whether to write a BL or BLX depending on the
408-
// value of bit 0 of Val. With bit 0 == 1 denoting Thumb. If the symbol is
409-
// not of type STT_FUNC then we must preserve the original instruction.
410-
// PLT entries are always ARM state so we know we don't need to interwork.
411-
bool isBlx = (read32le(loc) & 0xfe000000) == 0xfa000000;
412-
bool interwork = rel.sym && rel.sym->isFunc() && rel.expr != R_PLT_PC;
413-
if (interwork ? val & 1 : isBlx) {
405+
case R_ARM_CALL:
406+
// R_ARM_CALL is used for BL and BLX instructions, depending on the
407+
// value of bit 0 of Val, we must select a BL or BLX instruction
408+
if (val & 1) {
409+
// If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
414410
// The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
415411
checkInt(loc, val, 26, rel);
416412
write32le(loc, 0xfa000000 | // opcode
417413
((val & 2) << 23) | // H
418414
((val >> 2) & 0x00ffffff)); // imm24
419415
break;
420416
}
421-
// BLX (always unconditional) instruction to an ARM Target, select an
422-
// unconditional BL.
423-
write32le(loc, 0xeb000000 | (read32le(loc) & 0x00ffffff));
417+
if ((read32le(loc) & 0xfe000000) == 0xfa000000)
418+
// BLX (always unconditional) instruction to an ARM Target, select an
419+
// unconditional BL.
420+
write32le(loc, 0xeb000000 | (read32le(loc) & 0x00ffffff));
424421
// fall through as BL encoding is shared with B
425-
}
426422
LLVM_FALLTHROUGH;
427423
case R_ARM_JUMP24:
428424
case R_ARM_PC24:
@@ -447,23 +443,16 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
447443
((val >> 5) & 0x2000) | // J1
448444
((val >> 1) & 0x07ff)); // imm11
449445
break;
450-
case R_ARM_THM_CALL: {
451-
// R_ARM_THM_CALL is used for BL and BLX instructions, for symbols of type
452-
// STT_FUNC we choose whether to write a BL or BLX depending on the
453-
// value of bit 0 of Val. With bit 0 == 0 denoting ARM, if the symbol is
454-
// not of type STT_FUNC then we must preserve the original instruction.
455-
// PLT entries are always ARM state so we know we need to interwork.
456-
bool isBlx = (read16le(loc + 2) & 0x1000) == 0;
457-
bool interwork = (rel.sym && rel.sym->isFunc()) || rel.expr == R_PLT_PC;
458-
if (interwork ? (val & 1) == 0 : isBlx) {
459-
// We are writing a BLX. Ensure BLX destination is 4-byte aligned. As
460-
// the BLX instruction may only be two byte aligned. This must be done
461-
// before overflow check.
446+
case R_ARM_THM_CALL:
447+
// R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
448+
// value of bit 0 of Val, we must select a BL or BLX instruction
449+
if ((val & 1) == 0) {
450+
// Ensure BLX destination is 4-byte aligned. As BLX instruction may
451+
// only be two byte aligned. This must be done before overflow check
462452
val = alignTo(val, 4);
463-
write16le(loc + 2, read16le(loc + 2) & ~0x1000);
464-
} else {
465-
write16le(loc + 2, (read16le(loc + 2) & ~0x1000) | 1 << 12);
466453
}
454+
// Bit 12 is 0 for BLX, 1 for BL
455+
write16le(loc + 2, (read16le(loc + 2) & ~0x1000) | (val & 1) << 12);
467456
if (!config->armJ1J2BranchEncoding) {
468457
// Older Arm architectures do not support R_ARM_THM_JUMP24 and have
469458
// different 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 {
477466
((val >> 1) & 0x07ff)); // imm11
478467
break;
479468
}
480-
}
481469
// Fall through as rest of encoding is the same as B.W
482470
LLVM_FALLTHROUGH;
483471
case R_ARM_THM_JUMP24:

lld/test/ELF/arm-thumb-interwork-notfunc.s

Lines changed: 13 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ thumb_func_with_explicit_notype:
2323
/// All the symbols that are targets of the branch relocations do not have
2424
/// type STT_FUNC. LLD should not insert interworking thunks as non STT_FUNC
2525
/// symbols have no state information, the ABI assumes the user has manually
26-
/// done the interworking. For the BL and BLX instructions LLD should
27-
/// preserve the original instruction instead of writing out the correct one
28-
/// for the assumed state at the target.
26+
/// done the interworking.
2927
.section .arm_caller, "ax", %progbits
3028
.balign 4
3129
.arm
@@ -37,24 +35,10 @@ _start:
3735
b .thumb_target
3836
b thumb_func_with_notype
3937
b thumb_func_with_explicit_notype
40-
bl .arm_target
41-
bl arm_func_with_notype
42-
bl arm_func_with_explicit_notype
43-
bl .thumb_target
44-
bl thumb_func_with_notype
45-
bl thumb_func_with_explicit_notype
46-
blx .arm_target
47-
blx arm_func_with_notype
48-
blx arm_func_with_explicit_notype
49-
blx .thumb_target
50-
blx thumb_func_with_notype
51-
blx thumb_func_with_explicit_notype
5238

5339
.section .thumb_caller, "ax", %progbits
5440
.thumb
5541
.balign 4
56-
.global thumb_caller
57-
thumb_caller:
5842
b.w .arm_target
5943
b.w arm_func_with_notype
6044
b.w arm_func_with_explicit_notype
@@ -67,18 +51,6 @@ thumb_caller:
6751
beq.w .thumb_target
6852
beq.w thumb_func_with_notype
6953
beq.w thumb_func_with_explicit_notype
70-
bl .arm_target
71-
bl arm_func_with_notype
72-
bl arm_func_with_explicit_notype
73-
bl .thumb_target
74-
bl thumb_func_with_notype
75-
bl thumb_func_with_explicit_notype
76-
blx .arm_target
77-
blx arm_func_with_notype
78-
blx arm_func_with_explicit_notype
79-
blx .thumb_target
80-
blx thumb_func_with_notype
81-
blx thumb_func_with_explicit_notype
8254

8355
// CHECK: 00012008 _start:
8456
// CHECK-NEXT: 12008: b #-16
@@ -87,41 +59,15 @@ thumb_caller:
8759
// CHECK-NEXT: 12014: b #-24
8860
// CHECK-NEXT: 12018: b #-28
8961
// CHECK-NEXT: 1201c: b #-32
90-
// CHECK-NEXT: 12020: bl #-40
91-
// CHECK-NEXT: 12024: bl #-44
92-
// CHECK-NEXT: 12028: bl #-48
93-
// CHECK-NEXT: 1202c: bl #-48
94-
// CHECK-NEXT: 12030: bl #-52
95-
// CHECK-NEXT: 12034: bl #-56
96-
// CHECK-NEXT: 12038: blx #-64
97-
// CHECK-NEXT: 1203c: blx #-68
98-
// CHECK-NEXT: 12040: blx #-72
99-
// CHECK-NEXT: 12044: blx #-72
100-
// CHECK-NEXT: 12048: blx #-76
101-
// CHECK-NEXT: 1204c: blx #-80
102-
103-
// CHECK: 00012050 thumb_caller:
104-
// CHECK-NEXT: 12050: b.w #-84
105-
// CHECK-NEXT: 12054: b.w #-88
106-
// CHECK-NEXT: 12058: b.w #-92
107-
// CHECK-NEXT: 1205c: b.w #-92
108-
// CHECK-NEXT: 12060: b.w #-96
109-
// CHECK-NEXT: 12064: b.w #-100
110-
// CHECK-NEXT: 12068: beq.w #-108
111-
// CHECK-NEXT: 1206c: beq.w #-112
112-
// CHECK-NEXT: 12070: beq.w #-116
113-
// CHECK-NEXT: 12074: beq.w #-116
114-
// CHECK-NEXT: 12078: beq.w #-120
115-
// CHECK-NEXT: 1207c: beq.w #-124
116-
// CHECK-NEXT: 12080: bl #-132
117-
// CHECK-NEXT: 12084: bl #-136
118-
// CHECK-NEXT: 12088: bl #-140
119-
// CHECK-NEXT: 1208c: bl #-140
120-
// CHECK-NEXT: 12090: bl #-144
121-
// CHECK-NEXT: 12094: bl #-148
122-
// CHECK-NEXT: 12098: blx #-156
123-
// CHECK-NEXT: 1209c: blx #-160
124-
// CHECK-NEXT: 120a0: blx #-164
125-
// CHECK-NEXT: 120a4: blx #-164
126-
// CHECK-NEXT: 120a8: blx #-168
127-
// CHECK-NEXT: 120ac: blx #-172
62+
// CHECK: 12020: b.w #-36
63+
// CHECK-NEXT: 12024: b.w #-40
64+
// CHECK-NEXT: 12028: b.w #-44
65+
// CHECK-NEXT: 1202c: b.w #-44
66+
// CHECK-NEXT: 12030: b.w #-48
67+
// CHECK-NEXT: 12034: b.w #-52
68+
// CHECK-NEXT: 12038: beq.w #-60
69+
// CHECK-NEXT: 1203c: beq.w #-64
70+
// CHECK-NEXT: 12040: beq.w #-68
71+
// CHECK-NEXT: 12044: beq.w #-68
72+
// CHECK-NEXT: 12048: beq.w #-72
73+
// CHECK-NEXT: 1204c: beq.w #-76
Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// REQUIRES: arm
22
// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33
// RUN: ld.lld %t --shared -o %t.so
4-
// RUN: llvm-objdump -d --no-show-raw-insn -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
4+
// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
55
.syntax unified
66
.global sym1
77
.global elsewhere
@@ -10,51 +10,46 @@ sym1:
1010
b.w elsewhere
1111
b.w weakref
1212

13-
bl elsewhere
14-
bl weakref
15-
1613
// Check that we generate a thunk for an undefined symbol called via a plt
1714
// entry.
1815

1916
// CHECK: Disassembly of section .text:
2017
// CHECK-EMPTY:
2118
// CHECK-NEXT: sym1:
22-
// CHECK-NEXT: 11e0: b.w #12 <__ThumbV7PILongThunk_elsewhere>
23-
// CHECK-NEXT: b.w #20 <__ThumbV7PILongThunk_weakref>
24-
// CHECK-NEXT: blx #68
25-
// CHECK-NEXT: blx #80
19+
// CHECK-NEXT: 11e0: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere>
20+
// CHECK-NEXT: 11e4: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref>
2621
// CHECK: __ThumbV7PILongThunk_elsewhere:
27-
// CHECK-NEXT: 11f0: movw r12, #52
28-
// CHECK-NEXT: movt r12, #0
29-
// CHECK-NEXT: add r12, pc
30-
// CHECK-NEXT: bx r12
22+
// CHECK-NEXT: 11e8: 40 f2 2c 0c movw r12, #44
23+
// CHECK-NEXT: 11ec: c0 f2 00 0c movt r12, #0
24+
// CHECK-NEXT: 11f0: fc 44 add r12, pc
25+
// CHECK-NEXT: 11f2: 60 47 bx r12
3126
// CHECK: __ThumbV7PILongThunk_weakref:
32-
// CHECK-NEXT: 11fc: movw r12, #56
33-
// CHECK-NEXT: movt r12, #0
34-
// CHECK-NEXT: add r12, pc
35-
// CHECK-NEXT: bx r12
27+
// CHECK-NEXT: 11f4: 40 f2 30 0c movw r12, #48
28+
// CHECK-NEXT: 11f8: c0 f2 00 0c movt r12, #0
29+
// CHECK-NEXT: 11fc: fc 44 add r12, pc
30+
// CHECK-NEXT: 11fe: 60 47 bx r12
3631

3732
// CHECK: Disassembly of section .plt:
3833
// CHECK-EMPTY:
3934
// CHECK-NEXT: $a:
40-
// CHECK-NEXT: 1210: str lr, [sp, #-4]!
41-
// CHECK-NEXT: add lr, pc, #0, #12
42-
// CHECK-NEXT: add lr, lr, #8192
43-
// CHECK-NEXT: ldr pc, [lr, #148]!
35+
// CHECK-NEXT: 1200: 04 e0 2d e5 str lr, [sp, #-4]!
36+
// CHECK-NEXT: 1204: 00 e6 8f e2 add lr, pc, #0, #12
37+
// CHECK-NEXT: 1208: 02 ea 8e e2 add lr, lr, #8192
38+
// CHECK-NEXT: 120c: 94 f0 be e5 ldr pc, [lr, #148]!
4439
// CHECK: $d:
45-
// CHECK-NEXT: 1220: d4 d4 d4 d4 .word 0xd4d4d4d4
46-
// CHECK-NEXT: .word 0xd4d4d4d4
47-
// CHECK-NEXT: .word 0xd4d4d4d4
48-
// CHECK-NEXT: .word 0xd4d4d4d4
40+
// CHECK-NEXT: 1210: d4 d4 d4 d4 .word 0xd4d4d4d4
41+
// CHECK-NEXT: 1214: d4 d4 d4 d4 .word 0xd4d4d4d4
42+
// CHECK-NEXT: 1218: d4 d4 d4 d4 .word 0xd4d4d4d4
43+
// CHECK-NEXT: 121c: d4 d4 d4 d4 .word 0xd4d4d4d4
4944
// CHECK: $a:
50-
// CHECK-NEXT: 1230: add r12, pc, #0, #12
51-
// CHECK-NEXT: add r12, r12, #8192
52-
// CHECK-NEXT: ldr pc, [r12, #124]!
45+
// CHECK-NEXT: 1220: 00 c6 8f e2 add r12, pc, #0, #12
46+
// CHECK-NEXT: 1224: 02 ca 8c e2 add r12, r12, #8192
47+
// CHECK-NEXT: 1228: 7c f0 bc e5 ldr pc, [r12, #124]!
5348
// CHECK: $d:
54-
// CHECK-NEXT: 123c: d4 d4 d4 d4 .word 0xd4d4d4d4
49+
// CHECK-NEXT: 122c: d4 d4 d4 d4 .word 0xd4d4d4d4
5550
// CHECK: $a:
56-
// CHECK-NEXT: 1240: add r12, pc, #0, #12
57-
// CHECK-NEXT: add r12, r12, #8192
58-
// CHECK-NEXT: ldr pc, [r12, #112]!
51+
// CHECK-NEXT: 1230: 00 c6 8f e2 add r12, pc, #0, #12
52+
// CHECK-NEXT: 1234: 02 ca 8c e2 add r12, r12, #8192
53+
// CHECK-NEXT: 1238: 70 f0 bc e5 ldr pc, [r12, #112]!
5954
// CHECK: $d:
60-
// CHECK-NEXT: 124c: d4 d4 d4 d4 .word 0xd4d4d4d4
55+
// CHECK-NEXT: 123c: d4 d4 d4 d4 .word 0xd4d4d4d4

lld/test/ELF/arm-thumb-undefined-weak.s

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
.syntax unified
1111

1212
.weak target
13-
.type target, %function
1413

1514
.text
1615
.global _start

lld/test/ELF/arm-undefined-weak.s

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
.syntax unified
1313

1414
.weak target
15-
.type target, %function
1615

1716
.text
1817
.global _start

0 commit comments

Comments
 (0)