Index: ELF/Arch/ARM.cpp =================================================================== --- ELF/Arch/ARM.cpp +++ ELF/Arch/ARM.cpp @@ -58,7 +58,7 @@ GotEntrySize = 4; GotPltEntrySize = 4; PltEntrySize = 16; - PltHeaderSize = 20; + PltHeaderSize = 32; TrapInstr = 0xd4d4d4d4; // ARM uses Variant 1 TLS TcbSize = 8; @@ -184,32 +184,65 @@ 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(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 @@ 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(ISD); addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); Index: test/ELF/arm-branch-undef-weak-plt-thunk.s =================================================================== --- test/ELF/arm-branch-undef-weak-plt-thunk.s +++ test/ELF/arm-branch-undef-weak-plt-thunk.s @@ -26,10 +26,10 @@ // 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 Index: test/ELF/arm-exidx-shared.s =================================================================== --- test/ELF/arm-exidx-shared.s +++ test/ELF/arm-exidx-shared.s @@ -41,5 +41,5 @@ // 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 Index: test/ELF/arm-gnu-ifunc-plt.s =================================================================== --- test/ELF/arm-gnu-ifunc-plt.s +++ test/ELF/arm-gnu-ifunc-plt.s @@ -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 Index: test/ELF/arm-gnu-ifunc.s =================================================================== --- test/ELF/arm-gnu-ifunc.s +++ test/ELF/arm-gnu-ifunc.s @@ -111,30 +111,29 @@ // 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 + Index: test/ELF/arm-plt-reloc.s =================================================================== --- test/ELF/arm-plt-reloc.s +++ test/ELF/arm-plt-reloc.s @@ -32,51 +32,55 @@ // CHECK-NEXT: 11014: fb ff ff 0a beq #-20 // 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 @@ // 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 Index: test/ELF/arm-thumb-interwork-shared.s =================================================================== --- test/ELF/arm-thumb-interwork-shared.s +++ test/ELF/arm-thumb-interwork-shared.s @@ -19,34 +19,37 @@ // 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 + Index: test/ELF/arm-thumb-plt-range-thunk-os.s =================================================================== --- test/ELF/arm-thumb-plt-range-thunk-os.s +++ test/ELF/arm-thumb-plt-range-thunk-os.s @@ -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 @@ .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 Index: test/ELF/arm-thumb-plt-reloc.s =================================================================== --- test/ELF/arm-thumb-plt-reloc.s +++ test/ELF/arm-thumb-plt-reloc.s @@ -43,50 +43,54 @@ // .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 Index: test/ELF/arm-thunk-re-add.s =================================================================== --- test/ELF/arm-thunk-re-add.s +++ test/ELF/arm-thunk-re-add.s @@ -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 @@ 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 @@ 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 @@ // 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