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 = Config->LongPlt ? 20 : 16; TrapInstr = 0xd4d4d4d4; // ARM uses Variant 1 TLS TcbSize = 8; @@ -184,7 +184,9 @@ 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 @@ -198,18 +200,46 @@ 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 { + if (Config->LongPlt) { + writePltHeaderLong(Buf); + return; + } + + // 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)) + fatal(".got.plt is too far away from .plt, please use --long-plt."); + 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)); +} + void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const { auto *IS = cast(ISD); addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS); - addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS); + if (Config->LongPlt) + 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,10 +251,41 @@ 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 { + if (Config->LongPlt) { + writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff); + return; + } + + // 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. + 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)) + fatal(".got.plt is too far away from .plt, please use --long-plt."); + write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff)); + write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff)); + write32le(Buf + 8, PltData[2] | (Offset & 0xfff)); + // Pad out to 16-bytes to maintain alignment + write32le(Buf + 12, TrapInstr); +} + void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const { auto *IS = cast(ISD); addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); - addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); + if (Config->LongPlt) + addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); } bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -127,6 +127,7 @@ bool HasDynSymTab; bool ICF; bool ICFData; + bool LongPlt; bool MipsN32Abi = false; bool NoGnuUnique; bool NoUndefinedVersion; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -620,6 +620,7 @@ Config->ICF = Args.hasFlag(OPT_icf_all, OPT_icf_none, false); Config->ICFData = Args.hasArg(OPT_icf_data); Config->Init = Args.getLastArgValue(OPT_init, "_init"); + Config->LongPlt = Args.hasArg(OPT_long_plt); Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline); Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes); Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -156,6 +156,9 @@ defm library: Eq<"library">, HelpText<"Root name of library to use">, MetaVarName<"">; +def long_plt: F<"long-plt">, + HelpText<"Use longer range but slower .plt entries; Arm only.">; + def lto_O: J<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; @@ -409,7 +412,6 @@ def cref: F<"cref">; def detect_odr_violations: F<"detect-odr-violations">; def g: Flag<["-"], "g">; -def long_plt: F<"long-plt">; def no_add_needed: F<"no-add-needed">; def no_allow_shlib_undefined: F<"no-allow-shlib-undefined">; def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">; 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 @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t // RUN: ld.lld %t --shared -o %t.so // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 -// RUN: ld.lld %t2 %t.so -o %t3 +// RUN: ld.lld --long-plt %t2 %t.so -o %t3 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s // REQUIRES: arm Index: test/ELF/arm-exidx-shared.s =================================================================== --- test/ELF/arm-exidx-shared.s +++ test/ELF/arm-exidx-shared.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld --hash-style=sysv %t --shared -o %t2 2>&1 +// RUN: ld.lld --long-plt --hash-style=sysv %t --shared -o %t2 2>&1 // RUN: llvm-readobj --relocations %t2 | FileCheck %s // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXTAB %s // REQUIRES: arm Index: test/ELF/arm-gnu-ifunc-plt.s =================================================================== --- test/ELF/arm-gnu-ifunc-plt.s +++ test/ELF/arm-gnu-ifunc-plt.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o // RUN: ld.lld %t1.o --shared -o %t.so // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o -// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout +// RUN: ld.lld --long-plt --hash-style=sysv %t.so %t.o -o %tout // RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s Index: test/ELF/arm-gnu-ifunc.s =================================================================== --- test/ELF/arm-gnu-ifunc.s +++ test/ELF/arm-gnu-ifunc.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o -// RUN: ld.lld -static %t.o -o %tout +// RUN: ld.lld --long-plt -static %t.o -o %tout // RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s // REQUIRES: arm Index: test/ELF/arm-plt-reloc-short.s =================================================================== --- /dev/null +++ test/ELF/arm-plt-reloc-short.s @@ -0,0 +1,148 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 +// RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck %s +// RUN: llvm-readobj -s -r %t3 | FileCheck --check-prefix=DSOREL %s +// REQUIRES: arm + +// Test PLT entry generation for limited range PLT entries. These entries +// use the modified immediate addressing mode of the add instruction. This +// takes an 8-bit immediate and Rotates it Right (RoR) by an even number. The +// PLT entries use this to form bits 0x0NN00000 (RoR 12) and 0x000NN000 (RoR 20) +// of an address + .syntax unified + .text + .align 2 + .globl _start + .type _start,%function +_start: + b func1 + bl func2 + beq func3 + +// CHECK: Disassembly of section .text: +// CHECK-NEXT: func1: +// CHECK-NEXT: 1000: 1e ff 2f e1 bx lr +// CHECK: func2: +// CHECK-NEXT: 1004: 1e ff 2f e1 bx lr +// CHECK: func3: +// CHECK-NEXT: 1008: 1e ff 2f e1 bx lr +// CHECK: _start: +// CHECK-NEXT: 100c: 07 00 00 ea b #28 <$a> +// CHECK-NEXT: 1010: 0a 00 00 eb bl #40 <$a> +// CHECK-NEXT: 1014: 0d 00 00 0a beq #52 <$a> + +// CHECK: Disassembly of section .plt: +// CHECK-NEXT: $a: +// CHECK-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! +// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + 0xfdc = 0x2008 = .got.plt[3] +// CHECK-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 +// CHECK-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 +// CHECK-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! +// CHECK: $a: +// (0x1030 + 8) + (0 RoR 12) + (0 RoR 20) + 0xfd4 = 0x200c = .got.plt[4] +// CHECK-NEXT: 1030: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK-NEXT: 1034: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK-NEXT: 1038: d4 ff bc e5 ldr pc, [r12, #4052]! +// CHECK-NEXT: 103c: d4 d4 d4 d4 ldrble sp, [r4], #1236 +// CHECK: $a: +// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + 0xfc8 = 0x2010 = .got.plt[5] +// CHECK-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK-NEXT: 1048: c8 ff bc e5 ldr pc, [r12, #4040]! +// CHECK-NEXT: 104c: d4 d4 d4 d4 ldrble sp, [r4], #1236 +// CHECK: $a: +// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + 0xfbc = 0x2014 = .got.plt[6] +// CHECK-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK-NEXT: 1058: bc ff bc e5 ldr pc, [r12, #4028]! +// CHECK-NEXT: 105c: d4 d4 d4 d4 ldrble sp, [r4], #1236 + +// DSOREL: Name: .got.plt +// DSOREL-NEXT: Type: SHT_PROGBITS +// DSOREL-NEXT: Flags [ +// DSOREL-NEXT: SHF_ALLOC +// DSOREL-NEXT: SHF_WRITE +// DSOREL-NEXT: ] +// DSOREL-NEXT: Address: 0x2000 +// DSOREL: 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 +// 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: ff 03 00 ea b #4092 <$a> +// CHECKHIGH-NEXT: 1010: 02 04 00 eb bl #4104 <$a> +// CHECKHIGH-NEXT: 1014: 05 04 00 0a beq #4116 <$a> +// CHECKHIGH-NEXT: Disassembly of section .plt: +// CHECKHIGH-NEXT: $a: +// CHECKHIGH-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! +// (0x2004 + 8) + (0x10 RoR 12) + (0xfd RoR 20) + 0xffc = 0x1100008 .plt.got[3] +// 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: $a: +// (0x2010 + 8) + (0x10 RoR 12) + (0xfd RoR 20) + 0xff4 = 0x110000c .plt.got[4] +// CHECKHIGH-NEXT: 2010: 10 c6 8f e2 add r12, pc, #16, #12 +// CHECKHIGH-NEXT: 2014: fd ca 8c e2 add r12, r12, #1036288 +// CHECKHIGH-NEXT: 2018: f4 ff bc e5 ldr pc, [r12, #4084]! +// CHECKHIGH-NEXT: 201c: d4 d4 d4 d4 ldrble sp, [r4], #1236 +// CHECKHIGH: $a: +// (0x2020 + 8) + (0x10 RoR 12) + (0xfd RoR 20) + 0xfe8 = 0x1100010 .plt.got[5] +// 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: e8 ff bc e5 ldr pc, [r12, #4072]! +// CHECKHIGH-NEXT: 202c: d4 d4 d4 d4 ldrble sp, [r4], #1236 +// CHECKHIGH: $a: +// (0x2030 + 8) + (0x10 RoR 12) + (0xfd RoR 20) + 0xfdc = 0x1100014 .plt.got[6] +// 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: dc ff bc e5 ldr pc, [r12, #4060]! +// CHECKHIGH-NEXT: 203c: d4 d4 d4 d4 ldrble sp, [r4], #1236 + +// 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: 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 that we get an error when --long-plt is needed due to the displacement +// between the .plt and .got.plt not being representable. +// RUN: echo "SECTIONS { \ +// RUN: .text 0x1000 : { *(.text) } \ +// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ +// RUN: .got.plt 0x11111100 : { *(.got.plt) } \ +// RUN: }" > %t2.script +// RUN: not ld.lld --hash-style=sysv --script %t2.script -shared %t1 %t2 -o %t5 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s + +// We cannot represent negative offsets from .plt to .got.plt +// RUN: echo "SECTIONS { \ +// RUN: .text 0x1000 : { *(.text) } \ +// RUN: .got.plt 0x2000 : { *(.got.plt) } \ +// RUN: .plt 0x3000 : { *(.plt) *(.plt.*) } \ +// RUN: }" > %t3.script +// RUN: not ld.lld --hash-style=sysv --script %t3.script -shared %t1 %t2 -o %t6 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s + +// CHECK-ERROR: error: .got.plt is too far away from .plt, please use --long-plt. Index: test/ELF/arm-plt-reloc.s =================================================================== --- test/ELF/arm-plt-reloc.s +++ test/ELF/arm-plt-reloc.s @@ -1,8 +1,8 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 -// RUN: ld.lld %t1 %t2 -o %t +// RUN: ld.lld --long-plt %t1 %t2 -o %t // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t | FileCheck %s -// RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 +// RUN: ld.lld --long-plt --hash-style=sysv -shared %t1 %t2 -o %t3 // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s // REQUIRES: arm Index: test/ELF/arm-thumb-interwork-shared.s =================================================================== --- test/ELF/arm-thumb-interwork-shared.s +++ test/ELF/arm-thumb-interwork-shared.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t --shared -o %t.so +// RUN: ld.lld --long-plt %t --shared -o %t.so // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT // REQUIRES: arm 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 @@ -1,6 +1,6 @@ // REQUIRES: arm // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t --shared -o %t.so +// RUN: ld.lld --long-plt %t --shared -o %t.so // The output file is large, most of it zeroes. We dissassemble only the // parts we need to speed up the test and avoid a large output file // RUN: llvm-objdump -d %t.so -start-address=8388608 -stop-address=8388624 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s Index: test/ELF/arm-thumb-plt-reloc.s =================================================================== --- test/ELF/arm-thumb-plt-reloc.s +++ test/ELF/arm-thumb-plt-reloc.s @@ -1,8 +1,8 @@ // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2 -// RUN: ld.lld %t1 %t2 -o %t +// RUN: ld.lld --long-plt %t1 %t2 -o %t // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t | FileCheck %s -// RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 +// RUN: ld.lld --long-plt --hash-style=sysv -shared %t1 %t2 -o %t3 // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s Index: test/ELF/arm-thunk-re-add.s =================================================================== --- test/ELF/arm-thunk-re-add.s +++ test/ELF/arm-thunk-re-add.s @@ -1,6 +1,6 @@ // REQUIRES: arm // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t --shared -o %t.so +// RUN: ld.lld --long-plt %t --shared -o %t.so // The output file is large, most of it zeroes. We dissassemble only the // 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