[ELF] Optimize Arm PLT sequences

A more efficient PLT sequence can be used when the distance between the
.plt and the end of the .plt.got is less than 128 Megabytes, which is
frequently true. We fall back to the old sequence when the offset is larger
than 128 Megabytes. This gives us an alternative to forcing the longer
entries with --long-plt as we gracefully fall back to it as needed. 

See ELF for the ARM Architecture Appendix A for details of the PLT sequence.

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

llvm-svn: 320987
This commit is contained in:
Peter Smith 2017-12-18 14:46:27 +00:00
parent 190979189a
commit 3c73a41128
10 changed files with 458 additions and 183 deletions

View File

@ -58,7 +58,7 @@ ARM::ARM() {
GotEntrySize = 4;
GotPltEntrySize = 4;
PltEntrySize = 16;
PltHeaderSize = 20;
PltHeaderSize = 32;
TrapInstr = 0xd4d4d4d4;
// ARM uses Variant 1 TLS
TcbSize = 8;
@ -184,32 +184,65 @@ void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
write32le(Buf, S.getVA());
}
void ARM::writePltHeader(uint8_t *Buf) const {
// Long form PLT Heade that does not have any restrictions on the displacement
// of the .plt from the .plt.got.
static void writePltHeaderLong(uint8_t *Buf) {
const uint8_t PltData[] = {
0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]!
0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2
0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
0x08, 0xf0, 0xbe, 0xe5, // ldr pc, [lr, #8]
0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8
};
0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
0xd4, 0xd4, 0xd4, 0xd4};
memcpy(Buf, PltData, sizeof(PltData));
uint64_t GotPlt = InX::GotPlt->getVA();
uint64_t L1 = InX::Plt->getVA() + 8;
write32le(Buf + 16, GotPlt - L1 - 8);
}
// The default PLT header requires the .plt.got to be within 128 Mb of the
// .plt in the positive direction.
void ARM::writePltHeader(uint8_t *Buf) const {
// Use a similar sequence to that in writePlt(), the difference is the calling
// conventions mean we use lr instead of ip. The PLT entry is responsible for
// saving lr on the stack, the dynamic loader is responsible for reloading
// it.
const uint32_t PltData[] = {
0xe52de004, // L1: str lr, [sp,#-4]!
0xe28fe600, // add lr, pc, #0x0NN00000 &(.got.plt - L1 - 4)
0xe28eea00, // add lr, lr, #0x000NN000 &(.got.plt - L1 - 4)
0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
};
uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4;
if (!llvm::isUInt<27>(Offset)) {
// We cannot encode the Offset, use the long form.
writePltHeaderLong(Buf);
return;
}
write32le(Buf + 0, PltData[0]);
write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
write32le(Buf + 16, TrapInstr); // Pad to 32-byte boundary
write32le(Buf + 20, TrapInstr);
write32le(Buf + 24, TrapInstr);
write32le(Buf + 28, TrapInstr);
}
void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const {
auto *IS = cast<InputSection>(ISD);
addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
}
void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
uint64_t PltEntryAddr, int32_t Index,
unsigned RelOff) const {
// FIXME: Using simple code sequence with simple relocations.
// There is a more optimal sequence but it requires support for the group
// relocations. See ELF for the ARM Architecture Appendix A.3
// Long form PLT entries that do not have any restrictions on the displacement
// of the .plt from the .plt.got.
static void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr,
uint64_t PltEntryAddr, int32_t Index,
unsigned RelOff) {
const uint8_t PltData[] = {
0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2
0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
@ -221,6 +254,34 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
}
// The default PLT entries require the .plt.got to be within 128 Mb of the
// .plt in the positive direction.
void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
uint64_t PltEntryAddr, int32_t Index,
unsigned RelOff) const {
// The PLT entry is similar to the example given in Appendix A of ELF for
// the Arm Architecture. Instead of using the Group Relocations to find the
// optimal rotation for the 8-bit immediate used in the add instructions we
// hard code the most compact rotations for simplicity. This saves a load
// instruction over the long plt sequences.
const uint32_t PltData[] = {
0xe28fc600, // L1: add ip, pc, #0x0NN00000 Offset(&(.plt.got) - L1 - 8
0xe28cca00, // add ip, ip, #0x000NN000 Offset(&(.plt.got) - L1 - 8
0xe5bcf000, // ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8
};
uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8;
if (!llvm::isUInt<27>(Offset)) {
// We cannot encode the Offset, use the long form.
writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff);
return;
}
write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary
}
void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
auto *IS = cast<InputSection>(ISD);
addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);

View File

@ -26,10 +26,10 @@ _start:
// CHECK-NEXT: 11000: 00 00 00 ea b #0 <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for>
// CHECK-NEXT: 11004: 02 00 00 eb bl #8 <__ARMv7ABSLongThunk_bar2>
// CHECK: __ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for:
// CHECK-NEXT: 11008: 34 c0 01 e3 movw r12, #4148
// CHECK-NEXT: 1100c: 01 c2 40 e3 movt r12, #513
// CHECK-NEXT: 11010: 1c ff 2f e1 bx r12
// CHECK-NEXT: 11008: 40 c0 01 e3 movw r12, #4160
// CHECK-NEXT: 1100c: 01 c2 40 e3 movt r12, #513
// CHECK-NEXT: 11010: 1c ff 2f e1 bx r12
// CHECK: __ARMv7ABSLongThunk_bar2:
// CHECK-NEXT: 11014: 44 c0 01 e3 movw r12, #4164
// CHECK-NEXT: 11018: 01 c2 40 e3 movt r12, #513
// CHECK-NEXT: 1101c: 1c ff 2f e1 bx r12
// CHECK-NEXT: 11014: 50 c0 01 e3 movw r12, #4176
// CHECK-NEXT: 11018: 01 c2 40 e3 movt r12, #513
// CHECK-NEXT: 1101c: 1c ff 2f e1 bx r12

View File

@ -41,5 +41,5 @@ __aeabi_unwind_cpp_pr0:
// CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0
// CHECK-EXTAB: Contents of section .ARM.extab:
// 014c + 0ed8 = 0x1024 = __gxx_personality_v0(PLT)
// CHECK-EXTAB-NEXT: 014c d80e0000 b0b0b000 00000000
// 014c + 0ee4 = 0x1030 = __gxx_personality_v0(PLT)
// CHECK-EXTAB-NEXT: 014c e40e0000 b0b0b000 00000000

View File

@ -33,49 +33,49 @@
// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
// DISASM: bar:
// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr
// DISASM: _start:
// DISASM: _start:
// DISASM-NEXT: 11008: 14 00 00 eb bl #80
// DISASM-NEXT: 1100c: 17 00 00 eb bl #92
// DISASM: 11010: 00 00 00 00 .word 0x00000000
// DISASM: $d.1:
// DISASM-NEXT: 11010: 00 00 00 00 .word 0x00000000
// DISASM-NEXT: 11014: 04 00 00 00 .word 0x00000004
// DISASM: 11018: 05 00 00 eb bl #20
// DISASM-NEXT: 1101c: 08 00 00 eb bl #32
// DISASM: 11018: 08 00 00 eb bl #32
// DISASM-NEXT: 1101c: 0b 00 00 eb bl #44
// DISASM-NEXT: Disassembly of section .plt:
// DISASM-NEXT: $a:
// DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]!
// DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4]
// DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr
// DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]!
// DISASM-NEXT: 11024: 00 e6 8f e2 add lr, pc, #0, #12
// DISASM-NEXT: 11028: 00 ea 8e e2 add lr, lr, #0, #20
// DISASM-NEXT: 1102c: dc ff be e5 ldr pc, [lr, #4060]!
// DISASM: $d:
// DISASM-NEXT: 11030: d0 0f 00 00 .word 0x00000fd0
// DISASM-NEXT: 11030: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM-NEXT: 11034: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM-NEXT: 11038: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM: $a:
// DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc
// DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12]
// DISASM-NEXT: 11040: 00 c6 8f e2 add r12, pc, #0, #12
// DISASM-NEXT: 11044: 00 ca 8c e2 add r12, r12, #0, #20
// DISASM-NEXT: 11048: c4 ff bc e5 ldr pc, [r12, #4036]!
// DISASM: $d:
// DISASM-NEXT: 11040: cc 0f 00 00 .word 0x00000fcc
// DISASM-NEXT: 1104c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM: $a:
// DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc
// DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12]
// DISASM-NEXT: 11050: 00 c6 8f e2 add r12, pc, #0, #12
// DISASM-NEXT: 11054: 00 ca 8c e2 add r12, r12, #0, #20
// DISASM-NEXT: 11058: b8 ff bc e5 ldr pc, [r12, #4024]!
// DISASM: $d:
// DISASM-NEXT: 11050: c0 0f 00 00 .word 0x00000fc0
// Alignment to 16 byte boundary not strictly necessary on ARM, but harmless
// DISASM-NEXT: 11054: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM-NEXT: 11058: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM: $a:
// DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc
// DISASM-NEXT: 11068: 00 f0 9c e5 ldr pc, [r12]
// DISASM-NEXT: 11060: 00 c6 8f e2 add r12, pc, #0, #12
// DISASM-NEXT: 11064: 02 ca 8c e2 add r12, r12, #8192
// DISASM-NEXT: 11068: 18 f0 bc e5 ldr pc, [r12, #24]!
// DISASM: $d:
// DISASM-NEXT: 1106c: 14 20 00 00 .word 0x00002014
// DISASM-NEXT: 1106c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM: $a:
// DISASM-NEXT: 11070: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11074: 0f c0 8c e0 add r12, r12, pc
// DISASM-NEXT: 11078: 00 f0 9c e5 ldr pc, [r12]
// DISASM-NEXT: 11070: 00 c6 8f e2 add r12, pc, #0, #12
// DISASM-NEXT: 11074: 02 ca 8c e2 add r12, r12, #8192
// DISASM-NEXT: 11078: 0c f0 bc e5 ldr pc, [r12, #12]!
// DISASM: $d:
// DISASM-NEXT: 1107c: 08 20 00 00 .word 0x00002008
// DISASM-NEXT: 1107c: d4 d4 d4 d4 .word 0xd4d4d4d4
.syntax unified
.text

View File

@ -111,30 +111,29 @@ _start:
// DISASM: Disassembly of section .text:
// DISASM-NEXT: foo:
// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
// DISASM: bar:
// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr
// DISASM: _start:
// DISASM-NEXT: 11008: 04 00 00 eb bl #16
// DISASM-NEXT: 1100c: 07 00 00 eb bl #28
// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
// DISASM: bar:
// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr
// DISASM: _start:
// DISASM-NEXT: 11008: 04 00 00 eb bl #16
// DISASM-NEXT: 1100c: 07 00 00 eb bl #28
// 1 * 65536 + 244 = 0x100f4 __rel_iplt_start
// DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244
// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1
// DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244
// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1
// 1 * 65536 + 260 = 0x10104 __rel_iplt_end
// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260
// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1
// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260
// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1
// DISASM-NEXT: Disassembly of section .plt:
// DISASM: $a:
// DISASM-NEXT: 11020: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11024: 0f c0 8c e0 add r12, r12, pc
// 11024 + 8 + fd4 = 0x12000
// DISASM-NEXT: 11028: 00 f0 9c e5 ldr pc, [r12]
// DISASM-NEXT: $a:
// DISASM-NEXT: 11020: 00 c6 8f e2 add r12, pc, #0, #12
// DISASM-NEXT: 11024: 00 ca 8c e2 add r12, r12, #0, #20
// DISASM-NEXT: 11028: d8 ff bc e5 ldr pc, [r12, #4056]!
// DISASM: $d:
// DISASM-NEXT: 1102c: d4 0f 00 00 .word 0x00000fd4
// DISASM-NEXT: 1102c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM: $a:
// DISASM-NEXT: 11030: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11034: 0f c0 8c e0 add r12, r12, pc
// 11034 + 8 + fc8 = 0x12004
// DISASM-NEXT: 11038: 00 f0 9c e5 ldr pc, [r12]
// DISASM-NEXT: 11030: 00 c6 8f e2 add r12, pc, #0, #12
// DISASM-NEXT: 11034: 00 ca 8c e2 add r12, r12, #0, #20
// DISASM-NEXT: 11038: cc ff bc e5 ldr pc, [r12, #4044]!
// DISASM: $d:
// DISASM-NEXT: 1103c: c8 0f 00 00 .word 0x00000fc8
// DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4

View File

@ -32,51 +32,55 @@ _start:
// CHECK-NEXT: 11014: fb ff ff 0a beq #-20 <func3>
// Expect PLT entries as symbols can be preempted
// The .got.plt and .plt displacement is small so we can use small PLT entries.
// DSO: Disassembly of section .text:
// DSO-NEXT: func1:
// DSO-NEXT: 1000: 1e ff 2f e1 bx lr
// DSO-NEXT: 1000: 1e ff 2f e1 bx lr
// DSO: func2:
// DSO-NEXT: 1004: 1e ff 2f e1 bx lr
// DSO-NEXT: 1004: 1e ff 2f e1 bx lr
// DSO: func3:
// DSO-NEXT: 1008: 1e ff 2f e1 bx lr
// DSO-NEXT: 1008: 1e ff 2f e1 bx lr
// DSO: _start:
// S(0x1034) - P(0x100c) + A(-8) = 0x20 = 32
// DSO-NEXT: 100c: 08 00 00 ea b #32
// S(0x1044) - P(0x1010) + A(-8) = 0x2c = 44
// DSO-NEXT: 1010: 0b 00 00 eb bl #44
// S(0x1054) - P(0x1014) + A(-8) = 0x38 = 56
// DSO-NEXT: 1014: 0e 00 00 0a beq #56
// DSO: Disassembly of section .plt:
// S(0x1040) - P(0x100c) + A(-8) = 0x2c = 32
// DSO-NEXT: 100c: 0b 00 00 ea b #44
// S(0x1050) - P(0x1010) + A(-8) = 0x38 = 56
// DSO-NEXT: 1010: 0e 00 00 eb bl #56
// S(0x10160) - P(0x1014) + A(-8) = 0x44 = 68
// DSO-NEXT: 1014: 11 00 00 0a beq #68
// DSO-NEXT: Disassembly of section .plt:
// DSO-NEXT: $a:
// DSO-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
// DSO-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
// DSO-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
// DSO-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
// 0x1028 + 8 + 0fd0 = 0x2000
// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3]
// DSO-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12
// DSO-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20
// DSO-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]!
// DSO: $d:
// DSO-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0
// DSO-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSO-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSO-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSO-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSO: $a:
// DSO-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
// DSO-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
// DSO-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
// 0x1038 + 8 + 0fcc = 0x200c
// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c
// DSO-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12
// DSO-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20
// DSO-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]!
// DSO: $d:
// DSO-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc
// DSO-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSO: $a:
// DSO-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
// DSO-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
// DSO-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
// 0x1048 + 8 + 0fc0 = 0x2010
// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010
// DSO-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12
// DSO-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20
// DSO-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]!
// DSO: $d:
// DSO-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0
// DSO-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSO: $a:
// DSO-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4]
// DSO-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc
// DSO-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12]
// 0x1058 + 8 + 0fb4 = 0x2014
// (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014
// DSO-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12
// DSO-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20
// DSO-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]!
// DSO: $d:
// DSO-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4
// DSO-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOREL: Name: .got.plt
// DSOREL-NEXT: Type: SHT_PROGBITS
@ -96,3 +100,199 @@ _start:
// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0
// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0
// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0
// Test a large separation between the .plt and .got.plt
// The .got.plt and .plt displacement is large but still within the range
// of the short plt sequence.
// RUN: echo "SECTIONS { \
// RUN: .text 0x1000 : { *(.text) } \
// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \
// RUN: .got.plt 0x1100000 : { *(.got.plt) } \
// RUN: }" > %t.script
// RUN: ld.lld --hash-style=sysv --script %t.script -shared %t1 %t2 -o %t4
// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t4 | FileCheck --check-prefix=CHECKHIGH %s
// RUN: llvm-readobj -s -r %t4 | FileCheck --check-prefix=DSORELHIGH %s
// CHECKHIGH: Disassembly of section .text:
// CHECKHIGH-NEXT: func1:
// CHECKHIGH-NEXT: 1000: 1e ff 2f e1 bx lr
// CHECKHIGH: func2:
// CHECKHIGH-NEXT: 1004: 1e ff 2f e1 bx lr
// CHECKHIGH: func3:
// CHECKHIGH-NEXT: 1008: 1e ff 2f e1 bx lr
// CHECKHIGH: _start:
// CHECKHIGH-NEXT: 100c: 03 04 00 ea b #4108 <$a>
// CHECKHIGH-NEXT: 1010: 06 04 00 eb bl #4120 <$a>
// CHECKHIGH-NEXT: 1014: 09 04 00 0a beq #4132 <$a>
// CHECKHIGH-NEXT: Disassembly of section .plt:
// CHECKHIGH-NEXT: $a:
// CHECKHIGH-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]!
// CHECKHIGH-NEXT: 2004: 10 e6 8f e2 add lr, pc, #16, #12
// CHECKHIGH-NEXT: 2008: fd ea 8e e2 add lr, lr, #1036288
// CHECKHIGH-NEXT: 200c: fc ff be e5 ldr pc, [lr, #4092]!
// CHECKHIGH: $d:
// CHECKHIGH-NEXT: 2010: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKHIGH-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKHIGH-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKHIGH-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKHIGH: $a:
// CHECKHIGH-NEXT: 2020: 10 c6 8f e2 add r12, pc, #16, #12
// CHECKHIGH-NEXT: 2024: fd ca 8c e2 add r12, r12, #1036288
// CHECKHIGH-NEXT: 2028: e4 ff bc e5 ldr pc, [r12, #4068]!
// CHECKHIGH: $d:
// CHECKHIGH-NEXT: 202c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKHIGH: $a:
// CHECKHIGH-NEXT: 2030: 10 c6 8f e2 add r12, pc, #16, #12
// CHECKHIGH-NEXT: 2034: fd ca 8c e2 add r12, r12, #1036288
// CHECKHIGH-NEXT: 2038: d8 ff bc e5 ldr pc, [r12, #4056]!
// CHECKHIGH: $d:
// CHECKHIGH-NEXT: 203c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKHIGH: $a:
// CHECKHIGH-NEXT: 2040: 10 c6 8f e2 add r12, pc, #16, #12
// CHECKHIGH-NEXT: 2044: fd ca 8c e2 add r12, r12, #1036288
// CHECKHIGH-NEXT: 2048: cc ff bc e5 ldr pc, [r12, #4044]!
// CHECKHIGH: $d:
// CHECKHIGH-NEXT: 204c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSORELHIGH: Name: .got.plt
// DSORELHIGH-NEXT: Type: SHT_PROGBITS
// DSORELHIGH-NEXT: Flags [
// DSORELHIGH-NEXT: SHF_ALLOC
// DSORELHIGH-NEXT: SHF_WRITE
// DSORELHIGH-NEXT: ]
// DSORELHIGH-NEXT: Address: 0x1100000
// DSORELHIGH: Relocations [
// DSORELHIGH-NEXT: Section (6) .rel.plt {
// DSORELHIGH-NEXT: 0x110000C R_ARM_JUMP_SLOT func1 0x0
// DSORELHIGH-NEXT: 0x1100010 R_ARM_JUMP_SLOT func2 0x0
// DSORELHIGH-NEXT: 0x1100014 R_ARM_JUMP_SLOT func3 0x0
// Test a very large separation between the .plt and .got.plt so we must use
// large plt entries that do not have any range restriction.
// RUN: echo "SECTIONS { \
// RUN: .text 0x1000 : { *(.text) } \
// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \
// RUN: .got.plt 0x11111100 : { *(.got.plt) } \
// RUN: }" > %t2.script
// RUN: ld.lld --hash-style=sysv --script %t2.script -shared %t1 %t2 -o %t5
// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t5 | FileCheck --check-prefix=CHECKLONG %s
// RUN: llvm-readobj -s -r %t5 | FileCheck --check-prefix=DSORELLONG %s
// CHECKLONG: Disassembly of section .text:
// CHECKLONG-NEXT: func1:
// CHECKLONG-NEXT: 1000: 1e ff 2f e1 bx lr
// CHECKLONG: func2:
// CHECKLONG-NEXT: 1004: 1e ff 2f e1 bx lr
// CHECKLONG: func3:
// CHECKLONG-NEXT: 1008: 1e ff 2f e1 bx lr
// CHECKLONG: _start:
// CHECKLONG-NEXT: 100c: 03 04 00 ea b #4108 <$a>
// CHECKLONG-NEXT: 1010: 06 04 00 eb bl #4120 <$a>
// CHECKLONG-NEXT: 1014: 09 04 00 0a beq #4132 <$a>
// CHECKLONG-NEXT: Disassembly of section .plt:
// CHECKLONG-NEXT: $a:
// CHECKLONG-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]!
// CHECKLONG-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4]
// CHECKLONG-NEXT: 2008: 0e e0 8f e0 add lr, pc, lr
// CHECKLONG-NEXT: 200c: 08 f0 be e5 ldr pc, [lr, #8]!
// CHECKLONG: $d:
// CHECKLONG-NEXT: 2010: f0 f0 10 11 .word 0x1110f0f0
// CHECKLONG-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKLONG-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKLONG-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKLONG: $a:
// CHECKLONG-NEXT: 2020: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECKLONG-NEXT: 2024: 0f c0 8c e0 add r12, r12, pc
// CHECKLONG-NEXT: 2028: 00 f0 9c e5 ldr pc, [r12]
// CHECKLONG: $d:
// CHECKLONG-NEXT: 202c: e0 f0 10 11 .word 0x1110f0e0
// CHECKLONG: $a:
// CHECKLONG-NEXT: 2030: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECKLONG-NEXT: 2034: 0f c0 8c e0 add r12, r12, pc
// CHECKLONG-NEXT: 2038: 00 f0 9c e5 ldr pc, [r12]
// CHECKLONG: $d:
// CHECKLONG-NEXT: 203c: d4 f0 10 11 .word 0x1110f0d4
// CHECKLONG: $a:
// CHECKLONG-NEXT: 2040: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECKLONG-NEXT: 2044: 0f c0 8c e0 add r12, r12, pc
// CHECKLONG-NEXT: 2048: 00 f0 9c e5 ldr pc, [r12]
// CHECKLONG: $d:
// CHECKLONG-NEXT: 204c: c8 f0 10 11 .word 0x1110f0c8
// DSORELLONG: Name: .got.plt
// DSORELLONG-NEXT: Type: SHT_PROGBITS
// DSORELLONG-NEXT: Flags [
// DSORELLONG-NEXT: SHF_ALLOC
// DSORELLONG-NEXT: SHF_WRITE
// DSORELLONG-NEXT: ]
// DSORELLONG-NEXT: Address: 0x11111100
// DSORELLONG: Relocations [
// DSORELLONG-NEXT: Section (6) .rel.plt {
// DSORELLONG-NEXT: 0x1111110C R_ARM_JUMP_SLOT func1 0x0
// DSORELLONG-NEXT: 0x11111110 R_ARM_JUMP_SLOT func2 0x0
// DSORELLONG-NEXT: 0x11111114 R_ARM_JUMP_SLOT func3 0x0
// Test a separation between the .plt and .got.plt that is part in range of
// short table entries and part needing long entries. We use the long entries
// only when we need to.
// RUN: echo "SECTIONS { \
// RUN: .text 0x1000 : { *(.text) } \
// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \
// RUN: .got.plt 0x8002020 : { *(.got.plt) } \
// RUN: }" > %t3.script
// RUN: ld.lld --hash-style=sysv --script %t3.script -shared %t1 %t2 -o %t6
// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t6 | FileCheck --check-prefix=CHECKMIX %s
// RUN: llvm-readobj -s -r %t6 | FileCheck --check-prefix=DSORELMIX %s
// CHECKMIX: Disassembly of section .text:
// CHECKMIX-NEXT: func1:
// CHECKMIX-NEXT: 1000: 1e ff 2f e1 bx lr
// CHECKMIX: func2:
// CHECKMIX-NEXT: 1004: 1e ff 2f e1 bx lr
// CHECKMIX: func3:
// CHECKMIX-NEXT: 1008: 1e ff 2f e1 bx lr
// CHECKMIX: _start:
// CHECKMIX-NEXT: 100c: 03 04 00 ea b #4108 <$a>
// CHECKMIX-NEXT: 1010: 06 04 00 eb bl #4120 <$a>
// CHECKMIX-NEXT: 1014: 09 04 00 0a beq #4132 <$a>
// CHECKMIX-NEXT: Disassembly of section .plt:
// CHECKMIX-NEXT: $a:
// CHECKMIX-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]!
// CHECKMIX-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4]
// CHECKMIX-NEXT: 2008: 0e e0 8f e0 add lr, pc, lr
// CHECKMIX-NEXT: 200c: 08 f0 be e5 ldr pc, [lr, #8]!
// CHECKMIX: $d:
// CHECKMIX-NEXT: 2010: 10 00 00 08 .word 0x08000010
// CHECKMIX-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKMIX-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKMIX-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKMIX: $a:
// CHECKMIX-NEXT: 2020: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECKMIX-NEXT: 2024: 0f c0 8c e0 add r12, r12, pc
// CHECKMIX-NEXT: 2028: 00 f0 9c e5 ldr pc, [r12]
// CHECKMIX: $d:
// CHECKMIX-NEXT: 202c: 00 00 00 08 .word 0x08000000
// CHECKMIX: $a:
// CHECKMIX-NEXT: 2030: 7f c6 8f e2 add r12, pc, #133169152
// CHECKMIX-NEXT: 2034: ff ca 8c e2 add r12, r12, #1044480
// CHECKMIX-NEXT: 2038: f8 ff bc e5 ldr pc, [r12, #4088]!
// CHECKMIX: $d:
// CHECKMIX-NEXT: 203c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECKMIX: $a:
// CHECKMIX-NEXT: 2040: 7f c6 8f e2 add r12, pc, #133169152
// CHECKMIX-NEXT: 2044: ff ca 8c e2 add r12, r12, #1044480
// CHECKMIX-NEXT: 2048: ec ff bc e5 ldr pc, [r12, #4076]!
// CHECKMIX: $d:
// CHECKMIX-NEXT: 204c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSORELMIX: Name: .got.plt
// DSORELMIX-NEXT: Type: SHT_PROGBITS
// DSORELMIX-NEXT: Flags [
// DSORELMIX-NEXT: SHF_ALLOC
// DSORELMIX-NEXT: SHF_WRITE
// DSORELMIX-NEXT: ]
// DSORELMIX-NEXT: Address: 0x8002020
// DSORELMIX: Section (6) .rel.plt {
// DSORELMIX-NEXT: 0x800202C R_ARM_JUMP_SLOT func1 0x0
// DSORELMIX-NEXT: 0x8002030 R_ARM_JUMP_SLOT func2 0x0
// DSORELMIX-NEXT: 0x8002034 R_ARM_JUMP_SLOT func3 0x0

View File

@ -19,34 +19,37 @@ sym1:
// CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere>
// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref>
// CHECK: __ThumbV7PILongThunk_elsewhere:
// CHECK-NEXT: 1008: 40 f2 20 0c movw r12, #32
// CHECK-NEXT: 1008: 40 f2 2c 0c movw r12, #44
// CHECK-NEXT: 100c: c0 f2 00 0c movt r12, #0
// CHECK-NEXT: 1010: fc 44 add r12, pc
// CHECK-NEXT: 1012: 60 47 bx r12
// CHECK: __ThumbV7PILongThunk_weakref:
// CHECK-NEXT: 1014: 40 f2 24 0c movw r12, #36
// CHECK-NEXT: 1014: 40 f2 30 0c movw r12, #48
// CHECK-NEXT: 1018: c0 f2 00 0c movt r12, #0
// CHECK-NEXT: 101c: fc 44 add r12, pc
// CHECK-NEXT: 101e: 60 47 bx r12
// PLT: Disassembly of section .plt:
// PLT: $a:
// PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
// PLT-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
// PLT-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
// PLT-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
// PLT-NEXT: $a:
// PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
// PLT-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12
// PLT-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20
// PLT-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]!
// PLT: $d:
// PLT-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0
// PLT-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4
// PLT-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4
// PLT-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4
// PLT-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4
// PLT: $a:
// PLT-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
// PLT-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
// PLT-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
// PLT-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12
// PLT-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20
// PLT-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]!
// PLT: $d:
// PLT-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc
// PLT-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4
// PLT: $a:
// PLT-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
// PLT-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
// PLT-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
// PLT-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12
// PLT-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20
// PLT-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]!
// PLT: $d:
// PLT-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0
// PLT-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4

View File

@ -6,7 +6,7 @@
// RUN: llvm-objdump -d %t.so -start-address=8388608 -stop-address=8388624 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
// RUN: llvm-objdump -d %t.so -start-address=16777216 -stop-address=16777256 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
// RUN: llvm-objdump -d %t.so -start-address=25165824 -stop-address=25165828 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s
// RUN: llvm-objdump -d %t.so -start-address=25165828 -stop-address=25165908 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s
// RUN: llvm-objdump -d %t.so -start-address=25165828 -stop-address=25165924 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s
.syntax unified
.thumb
@ -39,50 +39,54 @@ preemptible:
.balign 0x0800000
bx lr
// CHECK2: __ThumbV7PILongThunk_elsewhere:
// CHECK2-NEXT: 1000004: 40 f2 14 0c movw r12, #20
// CHECK2-NEXT: 1000004: 40 f2 20 0c movw r12, #32
// CHECK2-NEXT: 1000008: c0 f2 80 0c movt r12, #128
// CHECK2-NEXT: 100000c: fc 44 add r12, pc
// CHECK2-NEXT: 100000e: 60 47 bx r12
// CHECK2: __ThumbV7PILongThunk_preemptible:
// CHECK2-NEXT: 1000010: 40 f2 18 0c movw r12, #24
// CHECK2-NEXT: 1000010: 40 f2 24 0c movw r12, #36
// CHECK2-NEXT: 1000014: c0 f2 80 0c movt r12, #128
// CHECK2-NEXT: 1000018: fc 44 add r12, pc
// CHECK2-NEXT: 100001a: 60 47 bx r12
// CHECK2: __ThumbV7PILongThunk_far_preemptible:
// CHECK2-NEXT: 100001c: 40 f2 1c 0c movw r12, #28
// CHECK2-NEXT: 100001c: 40 f2 28 0c movw r12, #40
// CHECK2-NEXT: 1000020: c0 f2 80 0c movt r12, #128
// CHECK2-NEXT: 1000024: fc 44 add r12, pc
// CHECK2-NEXT: 1000026: 60 47 bx r12
.section .text.3, "ax", %progbits
.balign 0x0800000
far_preemptible:
bl elsewhere
// CHECK3: far_preemptible:
// CHECK3: 1800000: 00 f0 10 e8 blx #32
// CHECK3: 1800000: 00 f0 16 e8 blx #44
// CHECK4: Disassembly of section .plt:
// CHECK4-NEXT: $a:
// CHECK4-NEXT: 1800010: 04 e0 2d e5 str lr, [sp, #-4]!
// CHECK4-NEXT: 1800014: 04 e0 9f e5 ldr lr, [pc, #4]
// CHECK4-NEXT: 1800018: 0e e0 8f e0 add lr, pc, lr
// CHECK4-NEXT: 180001c: 08 f0 be e5 ldr pc, [lr, #8]!
// CHECK4-NEXT: 1800010: 04 e0 2d e5 str lr, [sp, #-4]!
// CHECK4-NEXT: 1800014: 00 e6 8f e2 add lr, pc, #0, #12
// CHECK4-NEXT: 1800018: 00 ea 8e e2 add lr, lr, #0, #20
// CHECK4-NEXT: 180001c: ec ff be e5 ldr pc, [lr, #4076]!
// CHECK4: $d:
// CHECK4-NEXT: 1800020: e0 0f 00 00 .word 0x00000fe0
// CHECK4-NEXT: 1800020: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK4-NEXT: 1800024: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK4-NEXT: 1800028: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK4-NEXT: 180002c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK4: $a:
// CHECK4-NEXT: 1800024: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECK4-NEXT: 1800028: 0f c0 8c e0 add r12, r12, pc
// CHECK4-NEXT: 180002c: 00 f0 9c e5 ldr pc, [r12]
// CHECK4-NEXT: 1800030: 00 c6 8f e2 add r12, pc, #0, #12
// CHECK4-NEXT: 1800034: 00 ca 8c e2 add r12, r12, #0, #20
// CHECK4-NEXT: 1800038: d4 ff bc e5 ldr pc, [r12, #4052]!
// CHECK4: $d:
// CHECK4-NEXT: 1800030: dc 0f 00 00 .word 0x00000fdc
// CHECK4-NEXT: 180003c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK4: $a:
// CHECK4-NEXT: 1800034: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECK4-NEXT: 1800038: 0f c0 8c e0 add r12, r12, pc
// CHECK4-NEXT: 180003c: 00 f0 9c e5 ldr pc, [r12]
// CHECK4-NEXT: 1800040: 00 c6 8f e2 add r12, pc, #0, #12
// CHECK4-NEXT: 1800044: 00 ca 8c e2 add r12, r12, #0, #20
// CHECK4-NEXT: 1800048: c8 ff bc e5 ldr pc, [r12, #4040]!
// CHECK4: $d:
// CHECK4-NEXT: 1800040: d0 0f 00 00 .word 0x00000fd0
// CHECK4-NEXT: 180004c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK4: $a:
// CHECK4-NEXT: 1800044: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECK4-NEXT: 1800048: 0f c0 8c e0 add r12, r12, pc
// CHECK4-NEXT: 180004c: 00 f0 9c e5 ldr pc, [r12]
// CHECK4-NEXT: 1800050: 00 c6 8f e2 add r12, pc, #0, #12
// CHECK4-NEXT: 1800054: 00 ca 8c e2 add r12, r12, #0, #20
// CHECK4-NEXT: 1800058: bc ff bc e5 ldr pc, [r12, #4028]!
// CHECK4: $d:
// CHECK4-NEXT: 1800050: c4 0f 00 00 .word 0x00000fc4
// CHECK4-NEXT: 180005c: d4 d4 d4 d4 .word 0xd4d4d4d4

View File

@ -43,50 +43,54 @@ _start:
// .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-NEXT: func1:
// DSOTHUMB-NEXT: 1000: 70 47 bx lr
// DSOTHUMB: func2:
// DSOTHUMB-NEXT: 1002: 70 47 bx lr
// DSOTHUMB-NEXT: 1002: 70 47 bx lr
// DSOTHUMB: func3:
// DSOTHUMB-NEXT: 1004: 70 47 bx lr
// DSOTHUMB-NEXT: 1006: d4 d4
// DSOTHUMB-NEXT: 1004: 70 47 bx lr
// DSOTHUMB-NEXT: 1006: d4 d4 bmi #-88
// 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
// 0x1008 + 0x34 + 4 = 0x1040 = PLT func1
// DSOTHUMB-NEXT: 1008: 00 f0 1a e8 blx #52
// 0x100c + 0x40 + 4 = 0x1050 = PLT func2
// DSOTHUMB-NEXT: 100c: 00 f0 20 e8 blx #64
// 0x1010 + 0x4C + 4 = 0x1060 = PLT func3
// DSOTHUMB-NEXT: 1010: 00 f0 26 e8 blx #76
// DSOARM: Disassembly of section .plt:
// DSOARM-NEXT: $a:
// 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: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3]
// DSOARM-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12
// DSOARM-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20
// DSOARM-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]!
// DSOARM: $d:
// DSOARM-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0
// 0x1028 + 8 + 0fd0 = 0x2000
// DSOARM-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOARM-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOARM-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOARM-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOARM: $a:
// 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]
// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c
// DSOARM-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12
// DSOARM-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20
// DSOARM-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]!
// DSOARM: $d:
// DSOARM-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc
// 0x1038 + 8 + 0fcc = 0x200c
// DSOARM-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOARM: $a:
// 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]
// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010
// DSOARM-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12
// DSOARM-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20
// DSOARM-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]!
// DSOARM: $d:
// DSOARM-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0
// 0x1048 + 8 + 0fc0 = 0x2010
// DSOARM-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOARM: $a:
// 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]
// (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014
// DSOARM-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12
// DSOARM-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20
// DSOARM-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]!
// DSOARM: $d:
// DSOARM-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4
// 0x1058 + 8 + 0fb4 = 0x2014
// DSOARM-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DSOREL: Name: .got.plt
// DSOREL-NEXT: Type: SHT_PROGBITS

View File

@ -5,7 +5,7 @@
// parts we need to speed up the test and avoid a large output file
// RUN: llvm-objdump -d %t.so -start-address=16777220 -stop-address=16777244 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
// RUN: llvm-objdump -d %t.so -start-address=17825800 -stop-address=17825826 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
// RUN: llvm-objdump -d %t.so -start-address=17825824 -stop-address=17825876 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s
// RUN: llvm-objdump -d %t.so -start-address=17825824 -stop-address=17825892 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s
// A branch to a Thunk that we create on pass N, can drift out of range if
// other Thunks are added in between. In this case we must create a new Thunk
@ -65,12 +65,13 @@ tfunc\suff\():
FUNCTION 30
FUNCTION 31
// Precreated Thunk Pool goes here
// CHECK1: 1000004: 40 f2 24 0c movw r12, #36
// CHECK1: __ThumbV7PILongThunk_imported:
// CHECK1-NEXT: 1000004: 40 f2 30 0c movw r12, #48
// CHECK1-NEXT: 1000008: c0 f2 10 0c movt r12, #16
// CHECK1-NEXT: 100000c: fc 44 add r12, pc
// CHECK1-NEXT: 100000e: 60 47 bx r12
// CHECK1: __ThumbV7PILongThunk_imported2:
// CHECK1-NEXT: 1000010: 40 f2 28 0c movw r12, #40
// CHECK1-NEXT: 1000010: 40 f2 34 0c movw r12, #52
// CHECK1-NEXT: 1000014: c0 f2 10 0c movt r12, #16
// CHECK1-NEXT: 1000018: fc 44 add r12, pc
// CHECK1-NEXT: 100001a: 60 47 bx r12
@ -88,7 +89,7 @@ callers:
beq.w imported
b.w imported2
// CHECK2: __ThumbV7PILongThunk_imported:
// CHECK2-NEXT: 1100008: 40 f2 20 0c movw r12, #32
// CHECK2-NEXT: 1100008: 40 f2 2c 0c movw r12, #44
// CHECK2-NEXT: 110000c: c0 f2 00 0c movt r12, #0
// CHECK2-NEXT: 1100010: fc 44 add r12, pc
// CHECK2-NEXT: 1100012: 60 47 bx r12
@ -100,20 +101,23 @@ callers:
// CHECK3: Disassembly of section .plt:
// CHECK3-NEXT: $a:
// CHECK3-NEXT: 1100020: 04 e0 2d e5 str lr, [sp, #-4]!
// CHECK3-NEXT: 1100024: 04 e0 9f e5 ldr lr, [pc, #4]
// CHECK3-NEXT: 1100028: 0e e0 8f e0 add lr, pc, lr
// CHECK3-NEXT: 110002c: 08 f0 be e5 ldr pc, [lr, #8]!
// CHECK3-NEXT: 1100024: 00 e6 8f e2 add lr, pc, #0, #12
// CHECK3-NEXT: 1100028: 00 ea 8e e2 add lr, lr, #0, #20
// CHECK3-NEXT: 110002c: dc ff be e5 ldr pc, [lr, #4060]!
// CHECK3: $d:
// CHECK3-NEXT: 1100030: d0 0f 00 00 .word 0x00000fd0
// CHECK3-NEXT: 1100030: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK3-NEXT: 1100034: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK3-NEXT: 1100038: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK3-NEXT: 110003c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK3: $a:
// CHECK3-NEXT: 1100034: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECK3-NEXT: 1100038: 0f c0 8c e0 add r12, r12, pc
// CHECK3-NEXT: 110003c: 00 f0 9c e5 ldr pc, [r12]
// CHECK3-NEXT: 1100040: 00 c6 8f e2 add r12, pc, #0, #12
// CHECK3-NEXT: 1100044: 00 ca 8c e2 add r12, r12, #0, #20
// CHECK3-NEXT: 1100048: c4 ff bc e5 ldr pc, [r12, #4036]!
// CHECK3: $d:
// CHECK3-NEXT: 1100040: cc 0f 00 00 .word 0x00000fcc
// CHECK3-NEXT: 110004c: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK3: $a:
// CHECK3-NEXT: 1100044: 04 c0 9f e5 ldr r12, [pc, #4]
// CHECK3-NEXT: 1100048: 0f c0 8c e0 add r12, r12, pc
// CHECK3-NEXT: 110004c: 00 f0 9c e5 ldr pc, [r12]
// CHECK3-NEXT: 1100050: 00 c6 8f e2 add r12, pc, #0, #12
// CHECK3-NEXT: 1100054: 00 ca 8c e2 add r12, r12, #0, #20
// CHECK3-NEXT: 1100058: b8 ff bc e5 ldr pc, [r12, #4024]!
// CHECK3: $d:
// CHECK3-NEXT: 1100050: c0 0f 00 00 .word 0x00000fc0
// CHECK3-NEXT: 110005c: d4 d4 d4 d4 .word 0xd4d4d4d4