[PATCH] D41246: [LLD][ELF] Optimize Arm PLT entries
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 15 09:41:42 PST 2017
LGTM
Peter Smith via Phabricator <reviews at reviews.llvm.org> writes:
> peter.smith updated this revision to Diff 127147.
> peter.smith added a comment.
>
> I've implemented the suggestion to choose the form of PLT entry based on whether the offset to the .got.plt can be represented by the shorter encoding. To maintain 16-byte alignment of the entries I've increased the size of the header to 32-bytes. As the --long-plt doesn't do anything any more I've updated all the tests to use the new encoding. Apologies for the size of the diff.
>
>
> https://reviews.llvm.org/D41246
>
> Files:
> ELF/Arch/ARM.cpp
> test/ELF/arm-branch-undef-weak-plt-thunk.s
> test/ELF/arm-exidx-shared.s
> test/ELF/arm-gnu-ifunc-plt.s
> test/ELF/arm-gnu-ifunc.s
> test/ELF/arm-plt-reloc.s
> test/ELF/arm-thumb-interwork-shared.s
> test/ELF/arm-thumb-plt-range-thunk-os.s
> test/ELF/arm-thumb-plt-reloc.s
> test/ELF/arm-thunk-re-add.s
>
> 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
> 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-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-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-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 <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 @@
> // 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-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-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-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-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: 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<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 @@
> 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);
More information about the llvm-commits
mailing list