2 // RUN
: llvm-mc
-arm-add-build-attributes
-filetype
=obj
-triple
=armv7a-none-linux-gnueabi
%s
-o
%t
3 // RUN
: echo
"SECTIONS { \
4 // RUN: . = SIZEOF_HEADERS; \
5 // RUN: .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \
6 // RUN: .R_ARM_THM_JUMP_callee_1 : { *(.R_ARM_THM_JUMP_callee_low)} \
7 // RUN: .text : { *(.text) } \
8 // RUN: .arm_caller : { *(.arm_caller) } \
9 // RUN: .thumb_caller : { *(.thumb_caller) } \
10 // RUN: .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \
11 // RUN: .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } \
12 // RUN: .got.plt 0x18b4 : { } } " > %t.script
13 // RUN
: ld.lld
--script
%t.script
%t -o
%t2
14 // RUN
: llvm-objdump
--no-print-imm-hex
-d
--no-show-raw-insn
%t2 | FileCheck
--check-prefix
=CHECK-THUMB
--check-prefix
=CHECK-ABS-THUMB
%s
15 // RUN
: llvm-objdump
--no-print-imm-hex
-d
--no-show-raw-insn
--triple
=armv7a-none-linux-gnueabi
%t2 | FileCheck
--check-prefix
=CHECK-ARM
--check-prefix
=CHECK-ARM-ABS-ARM
%s
16 // RUN
: ld.lld
--script
%t.script
%t -pie
-o
%t3
17 // RUN
: llvm-objdump
--no-print-imm-hex
-d
--no-show-raw-insn
%t3 | FileCheck
--check-prefix
=CHECK-THUMB
--check-prefix
=CHECK-PI-THUMB
%s
18 // RUN
: llvm-objdump
--no-print-imm-hex
-d
--no-show-raw-insn
--triple
=armv7a-none-linux-gnueabi
%t3 | FileCheck
--check-prefix
=CHECK-ARM
--check-prefix
=CHECK-PI-ARM
%s
19 // RUN
: ld.lld
--script
%t.script
%t --shared
-o
%t4
20 // RUN
: llvm-readobj
-S
-r
%t4 | FileCheck
-check-prefix
=CHECK-DSO-REL
%s
21 // RUN
: llvm-objdump
--no-print-imm-hex
-d
--no-show-raw-insn
--triple
=armv7a-none-linux-gnueabi
%t4 | FileCheck
-check-prefix
=CHECK-ARM-PLT
%s
22 /// Test ARM Thumb Interworking
23 /// The file is linked
and checked
3 times to check the following contexts
24 /// - Absolute executables
, absolute Thunks are used.
25 /// - Position independent executables
, position independent Thunks are used.
26 /// - Shared object
, position independent Thunks to PLT entries are used.
30 /// Target Sections for thunks at
a lower address than the callers.
31 .section .R_ARM_JUMP24_callee_low, "ax", %progbits
35 .type thumb_callee1, %function
39 // CHECK-THUMB
: Disassembly of section
.R_ARM_JUMP24_callee_1:
41 // CHECK-THUMB
: <thumb_callee1
>:
42 // CHECK-THUMB
: 1000: bx
lr
43 .section .R_ARM_THM_JUMP_callee_low, "ax", %progbits
47 .type arm_callee1, %function
50 // Disassembly of section
.R_ARM_THM_JUMP_callee_1:
51 // CHECK-ARM
: <arm_callee1
>:
52 // CHECK-ARM-NEXT
: 1100: bx
lr
55 /// At present ARM
and Thumb interworking thunks are always added to the calling
57 .section .arm_caller, "ax", %progbits
61 .type arm_caller, %function
63 /// If target supports BLX
and target is in range we don
't need an
64 /// interworking thunk for a BL or BLX instruction.
67 /// A B instruction can't be transformed into
a BLX
and needs an interworking
70 /// As long as the thunk is in range it can
be reused.
72 /// There can
be more than one thunk associated with
a section.
75 /// In range ARM targets do
not require interworking thunks.
80 // CHECK-ARM-ABS-ARM
: Disassembly of section
.arm_caller:
81 // CHECK-ARM-ABS-ARM-EMPTY
:
82 // CHECK-ARM-ABS-ARM-NEXT
: <arm_caller
>:
83 // CHECK-ARM-ABS-ARM-NEXT
: 1300: blx
0x1000 <thumb_callee1
>
84 // CHECK-ARM-ABS-ARM-NEXT
: 1304: blx
0x1000 <thumb_callee1
>
85 // CHECK-ARM-ABS-ARM-NEXT
: 1308: b 0x1328 <__ARMv7ABSLongThunk_thumb_callee1
>
86 // CHECK-ARM-ABS-ARM-NEXT
: 130c
: b 0x1328 <__ARMv7ABSLongThunk_thumb_callee1
>
87 // CHECK-ARM-ABS-ARM-NEXT
: 1310: b 0x1334 <__ARMv7ABSLongThunk_thumb_callee2
>
88 // CHECK-ARM-ABS-ARM-NEXT
: 1314: b 0x1340 <__ARMv7ABSLongThunk_thumb_callee3
>
89 // CHECK-ARM-ABS-ARM-NEXT
: 1318: b 0x1100 <arm_callee1
>
90 // CHECK-ARM-ABS-ARM-NEXT
: 131c
: beq 0x1600 <arm_callee2
>
91 // CHECK-ARM-ABS-ARM-NEXT
: 1320: bne 0x1604 <arm_callee3
>
92 // CHECK-ARM-ABS-ARM-NEXT
: 1324: bx
lr
93 // CHECK-ARM-ABS-ARM
: <__ARMv7ABSLongThunk_thumb_callee1
>:
94 // 0x1001 = thumb_callee1
95 // CHECK-ARM-ABS-ARM-NEXT
: 1328: movw
r12, #4097
96 // CHECK-ARM-ABS-ARM-NEXT
: 132c
: movt
r12, #0
97 // CHECK-ARM-ABS-ARM-NEXT
: 1330: bx
r12
98 // 0x1501 = thumb_callee2
99 // CHECK-ARM-ABS-ARM
: <__ARMv7ABSLongThunk_thumb_callee2
>:
100 // CHECK-ARM-ABS-ARM-NEXT
: 1334: movw
r12, #5377
101 // CHECK-ARM-ABS-ARM-NEXT
: 1338: movt
r12, #0
102 // CHECK-ARM-ABS-ARM-NEXT
: 133c
: bx
r12
103 // 0x1503 = thumb_callee3
104 // CHECK-ARM-ABS-ARM
: <__ARMv7ABSLongThunk_thumb_callee3
>:
105 // CHECK-ARM-ABS-ARM-NEXT
: 1340: movw
r12, #5379
106 // CHECK-ARM-ABS-ARM-NEXT
: 1344: movt
r12, #0
107 // CHECK-ARM-ABS-ARM-NEXT
: 1348: bx
r12
109 // CHECK-PI-ARM
: Disassembly of section
.arm_caller:
110 // CHECK-PI-ARM-EMPTY
:
111 // CHECK-PI-ARM-NEXT
: <arm_caller
>:
112 // CHECK-PI-ARM-NEXT
: 1300: blx
0x1000 <thumb_callee1
>
113 // CHECK-PI-ARM-NEXT
: 1304: blx
0x1000 <thumb_callee1
>
114 // CHECK-PI-ARM-NEXT
: 1308: b 0x1328 <__ARMV7PILongThunk_thumb_callee1
>
115 // CHECK-PI-ARM-NEXT
: 130c
: b 0x1328 <__ARMV7PILongThunk_thumb_callee1
>
116 // CHECK-PI-ARM-NEXT
: 1310: b 0x1338 <__ARMV7PILongThunk_thumb_callee2
>
117 // CHECK-PI-ARM-NEXT
: 1314: b 0x1348 <__ARMV7PILongThunk_thumb_callee3
>
118 // CHECK-PI-ARM-NEXT
: 1318: b 0x1100 <arm_callee1
>
119 // CHECK-PI-ARM-NEXT
: 131c
: beq 0x1600 <arm_callee2
>
120 // CHECK-PI-ARM-NEXT
: 1320: bne 0x1604 <arm_callee3
>
121 // CHECK-PI-ARM-NEXT
: 1324: bx
lr
122 // CHECK-PI-ARM
: <__ARMV7PILongThunk_thumb_callee1
>:
123 // CHECK-PI-ARM-NEXT
: 1328: movw
r12, #64713
124 // CHECK-PI-ARM-NEXT
: 132c
: movt
r12, #65535
125 // CHECK-PI-ARM-NEXT
: 1330: add r12, r12, pc
126 // CHECK-PI-ARM-NEXT
: 1334: bx
r12
127 // CHECK-PI-ARM
: <__ARMV7PILongThunk_thumb_callee2
>:
128 // CHECK-PI-ARM-NEXT
: 1338: movw
r12, #441
129 // CHECK-PI-ARM-NEXT
: 133c
: movt
r12, #0
130 // CHECK-PI-ARM-NEXT
: 1340: add r12, r12, pc
131 // CHECK-PI-ARM-NEXT
: 1344: bx
r12
132 // CHECK-PI-ARM
: <__ARMV7PILongThunk_thumb_callee3
>:
133 // CHECK-PI-ARM-NEXT
: 1348: movw
r12, #427
134 // CHECK-PI-ARM-NEXT
: 134c
: movt
r12, #0
135 // CHECK-PI-ARM-NEXT
: 1350: add r12, r12, pc
136 // CHECK-PI-ARM-NEXT
: 1354: bx
r12
138 /// All PLT entries are ARM
, callers via PLT no need for interworking thunks.
139 // CHECK-ARM-PLT
: Disassembly of section
.arm_caller:
140 // CHECK-ARM-PLT-EMPTY
:
141 // CHECK-ARM-PLT-NEXT
: <arm_caller
>:
142 // CHECK-ARM-PLT-NEXT
: 1300: bl 0x1630
143 // CHECK-ARM-PLT-NEXT
: 1304: bl 0x1630
144 // CHECK-ARM-PLT-NEXT
: 1308: b 0x1630
145 // CHECK-ARM-PLT-NEXT
: 130c
: b 0x1630
146 // CHECK-ARM-PLT-NEXT
: 1310: b 0x1660
147 // CHECK-ARM-PLT-NEXT
: 1314: b 0x1670
148 // CHECK-ARM-PLT-NEXT
: 1318: b 0x1640
149 // CHECK-ARM-PLT-NEXT
: 131c
: beq 0x1680
150 // CHECK-ARM-PLT-NEXT
: 1320: bne 0x1690
151 // CHECK-ARM-PLT-NEXT
: 1324: bx
lr
153 .section .thumb_caller, "ax", %progbits
157 .type thumb_caller, %function
159 /// If target supports BLX
and target is in range we don
't need an
160 /// interworking thunk for a BL or BLX instruction.
163 /// A B instruction can't be transformed into
a BLX
and needs an interworking
166 /// As long as the thunk is in range it can
be reused
168 /// There can
be more than one thunk associated with
a section
170 /// Conditional branches also require interworking thunks
, they can use the
171 /// same interworking thunks.
175 // CHECK-ABS-THUMB
: Disassembly of section
.thumb_caller:
176 // CHECK-ABS-THUMB-EMPTY
:
177 // CHECK-ABS-THUMB-NEXT
: <thumb_caller
>:
178 // CHECK-ABS-THUMB-NEXT
: 1400: blx
0x1100 <arm_callee1
>
179 // CHECK-ABS-THUMB-NEXT
: 1404: blx
0x1100 <arm_callee1
>
180 // CHECK-ABS-THUMB-NEXT
: 1408: b.w
0x1420 <__Thumbv7ABSLongThunk_arm_callee1
>
181 // CHECK-ABS-THUMB-NEXT
: 140c
: b.w
0x142a <__Thumbv7ABSLongThunk_arm_callee2
>
182 // CHECK-ABS-THUMB-NEXT
: 1410: b.w
0x1434 <__Thumbv7ABSLongThunk_arm_callee3
>
183 // CHECK-ABS-THUMB-NEXT
: 1414: beq.w
0x1420 <__Thumbv7ABSLongThunk_arm_callee1
>
184 // CHECK-ABS-THUMB-NEXT
: 1418: beq.w
0x142a <__Thumbv7ABSLongThunk_arm_callee2
>
185 // CHECK-ABS-THUMB-NEXT
: 141c
: bne.w
0x1434 <__Thumbv7ABSLongThunk_arm_callee3
>
186 // CHECK-ABS-THUMB
: <__Thumbv7ABSLongThunk_arm_callee1
>:
187 // CHECK-ABS-THUMB-NEXT
: 1420: movw
r12, #4352
188 // CHECK-ABS-THUMB-NEXT
: 1424: movt
r12, #0
189 // CHECK-ABS-THUMB-NEXT
: 1428: bx
r12
190 // CHECK-ABS-THUMB
: <__Thumbv7ABSLongThunk_arm_callee2
>:
191 // CHECK-ABS-THUMB-NEXT
: 142a: movw
r12, #5632
192 // CHECK-ABS-THUMB-NEXT
: 142e
: movt
r12, #0
193 // CHECK-ABS-THUMB-NEXT
: 1432: bx
r12
194 // CHECK-ABS-THUMB
: <__Thumbv7ABSLongThunk_arm_callee3
>:
195 // CHECK-ABS-THUMB-NEXT
: 1434: movw
r12, #5636
196 // CHECK-ABS-THUMB-NEXT
: 1438: movt
r12, #0
197 // CHECK-ABS-THUMB-NEXT
: 143c
: bx
r12
199 // CHECK-PI-THUMB
: Disassembly of section
.thumb_caller:
200 // CHECK-PI-THUMB-EMPTY
:
201 // CHECK-PI-THUMB-NEXT
: <thumb_caller
>:
202 // CHECK-PI-THUMB-NEXT
: 1400: blx
0x1100 <arm_callee1
>
203 // CHECK-PI-THUMB-NEXT
: 1404: blx
0x1100 <arm_callee1
>
204 // CHECK-PI-THUMB-NEXT
: 1408: b.w
0x1420 <__ThumbV7PILongThunk_arm_callee1
>
205 // CHECK-PI-THUMB-NEXT
: 140c
: b.w
0x142c <__ThumbV7PILongThunk_arm_callee2
>
206 // CHECK-PI-THUMB-NEXT
: 1410: b.w
0x1438 <__ThumbV7PILongThunk_arm_callee3
>
207 // CHECK-PI-THUMB-NEXT
: 1414: beq.w
0x1420 <__ThumbV7PILongThunk_arm_callee1
>
208 // CHECK-PI-THUMB-NEXT
: 1418: beq.w
0x142c <__ThumbV7PILongThunk_arm_callee2
>
209 // CHECK-PI-THUMB-NEXT
: 141c
: bne.w
0x1438 <__ThumbV7PILongThunk_arm_callee3
>
210 // CHECK-PI-THUMB
: <__ThumbV7PILongThunk_arm_callee1
>:
211 // CHECK-PI-THUMB-NEXT
: 1420: movw
r12, #64724
212 // CHECK-PI-THUMB-NEXT
: 1424: movt
r12, #65535
213 // CHECK-PI-THUMB-NEXT
: 1428: add r12, pc
214 // CHECK-PI-THUMB-NEXT
: 142a: bx
r12
215 // CHECK-PI-THUMB
: <__ThumbV7PILongThunk_arm_callee2
>:
216 // CHECK-PI-THUMB-NEXT
: 142c
: movw
r12, #456
217 // CHECK-PI-THUMB-NEXT
: 1430: movt
r12, #0
218 // CHECK-PI-THUMB-NEXT
: 1434: add r12, pc
219 // CHECK-PI-THUMB-NEXT
: 1436: bx
r12
220 // CHECK-PI-THUMB
: <__ThumbV7PILongThunk_arm_callee3
>:
221 // CHECK-PI-THUMB-NEXT
: 1438: movw
r12, #448
222 // CHECK-PI-THUMB-NEXT
: 143c
: movt
r12, #0
223 // CHECK-PI-THUMB-NEXT
: 1440: add r12, pc
224 // CHECK-PI-THUMB-NEXT
: 1442: bx
r12
226 /// Thumb calls need to change state to reach PLT
227 /// bl can change to blx to PLT entries
, branches
228 /// need
a state change thunk.
229 // CHECK-ARM-PLT
: Disassembly of section
.thumb_caller:
230 // CHECK-ARM-PLT-EMPTY
:
231 // CHECK-ARM-PLT-NEXT
: <thumb_caller
>:
232 // CHECK-ARM-PLT-NEXT
: 1400: blx
0x1640
233 // CHECK-ARM-PLT-NEXT
: 1404: blx
0x1640
234 // CHECK-ARM-PLT-NEXT
: 1408: b.w
0x1420 <__ThumbV7PILongThunk_arm_callee1
>
235 // CHECK-ARM-PLT-NEXT
: 140c
: b.w
0x142c <__ThumbV7PILongThunk_arm_callee2
>
236 // CHECK-ARM-PLT-NEXT
: 1410: b.w
0x1438 <__ThumbV7PILongThunk_arm_callee3
>
237 // CHECK-ARM-PLT-NEXT
: 1414: beq.w
0x1420 <__ThumbV7PILongThunk_arm_callee1
>
238 // CHECK-ARM-PLT-NEXT
: 1418: beq.w
0x142c <__ThumbV7PILongThunk_arm_callee2
>
239 // CHECK-ARM-PLT-NEXT
: 141c
: bne.w
0x1438 <__ThumbV7PILongThunk_arm_callee3
>
241 /// Target Sections for thunks at
a higher address than the callers.
242 .section .R_ARM_JUMP24_callee_high, "ax", %progbits
246 .type thumb_callee2, %function
251 .type thumb_callee3, %function
254 // CHECK-THUMB
: Disassembly of section
.R_ARM_JUMP24_callee_2:
255 // CHECK-THUMB-EMPTY
:
256 // CHECK-THUMB-NEXT
: <thumb_callee2
>:
257 // CHECK-THUMB-NEXT
: 1500: bx
lr
258 // CHECK-THUMB
: <thumb_callee3
>:
259 // CHECK-THUMB-NEXT
: 1502: bx
lr
261 .section .R_ARM_THM_JUMP_callee_high, "ax", %progbits
265 .type arm_callee2, %function
269 .type arm_callee3, %function
272 // CHECK-ARM
: Disassembly of section
.R_ARM_THM_JUMP_callee_2:
274 // CHECK-ARM-NEXT
: <arm_callee2
>:
275 // CHECK-ARM-NEXT
: 1600: bx
lr
276 // CHECK-ARM
: <arm_callee3
>:
277 // CHECK-ARM-NEXT
: 1604: bx
lr
279 /// _start section just calls the arm
and thumb calling sections
284 .type _start, %function
290 // CHECK-ARM-PLT
: Disassembly of section
.plt:
291 // CHECK-ARM-PLT-EMPTY
:
292 // CHECK-ARM-PLT-NEXT
: 00001610 <.plt>:
293 // CHECK-ARM-PLT-NEXT
: 1610: str
lr, [sp
, #-4]!
294 // CHECK-ARM-PLT-NEXT
: 1614: add lr, pc
, #0, #12
295 // CHECK-ARM-PLT-NEXT
: 1618: add lr, lr, #0, #20
296 // CHECK-ARM-PLT-NEXT
: 161c
: ldr pc
, [lr, #672]!
297 // CHECK-ARM-PLT-NEXT
: 1620: d4 d4 d4 d4
.word 0xd4d4d4d4
298 // CHECK-ARM-PLT-NEXT
: 1624: d4 d4 d4 d4
.word 0xd4d4d4d4
299 // CHECK-ARM-PLT-NEXT
: 1628: d4 d4 d4 d4
.word 0xd4d4d4d4
300 // CHECK-ARM-PLT-NEXT
: 162c
: d4 d4 d4 d4
.word 0xd4d4d4d4
301 // CHECK-ARM-PLT-NEXT
: 1630: add r12, pc
, #0, #12
302 // CHECK-ARM-PLT-NEXT
: 1634: add r12, r12, #0, #20
303 // CHECK-ARM-PLT-NEXT
: 1638: ldr pc
, [r12, #648]!
304 // CHECK-ARM-PLT-NEXT
: 163c
: d4 d4 d4 d4
.word 0xd4d4d4d4
305 // CHECK-ARM-PLT-NEXT
: 1640: add r12, pc
, #0, #12
306 // CHECK-ARM-PLT-NEXT
: 1644: add r12, r12, #0, #20
307 // CHECK-ARM-PLT-NEXT
: 1648: ldr pc
, [r12, #636]!
308 // CHECK-ARM-PLT-NEXT
: 164c
: d4 d4 d4 d4
.word 0xd4d4d4d4
309 // CHECK-ARM-PLT-NEXT
: 1650: add r12, pc
, #0, #12
310 // CHECK-ARM-PLT-NEXT
: 1654: add r12, r12, #0, #20
311 // CHECK-ARM-PLT-NEXT
: 1658: ldr pc
, [r12, #624]!
312 // CHECK-ARM-PLT-NEXT
: 165c
: d4 d4 d4 d4
.word 0xd4d4d4d4
313 // CHECK-ARM-PLT-NEXT
: 1660: add r12, pc
, #0, #12
314 // CHECK-ARM-PLT-NEXT
: 1664: add r12, r12, #0, #20
315 // CHECK-ARM-PLT-NEXT
: 1668: ldr pc
, [r12, #612]!
316 // CHECK-ARM-PLT-NEXT
: 166c
: d4 d4 d4 d4
.word 0xd4d4d4d4
317 // CHECK-ARM-PLT-NEXT
: 1670: add r12, pc
, #0, #12
318 // CHECK-ARM-PLT-NEXT
: 1674: add r12, r12, #0, #20
319 // CHECK-ARM-PLT-NEXT
: 1678: ldr pc
, [r12, #600]!
320 // CHECK-ARM-PLT-NEXT
: 167c
: d4 d4 d4 d4
.word 0xd4d4d4d4
321 // CHECK-ARM-PLT-NEXT
: 1680: add r12, pc
, #0, #12
322 // CHECK-ARM-PLT-NEXT
: 1684: add r12, r12, #0, #20
323 // CHECK-ARM-PLT-NEXT
: 1688: ldr pc
, [r12, #588]!
324 // CHECK-ARM-PLT-NEXT
: 168c
: d4 d4 d4 d4
.word 0xd4d4d4d4
325 // CHECK-ARM-PLT-NEXT
: 1690: add r12, pc
, #0, #12
326 // CHECK-ARM-PLT-NEXT
: 1694: add r12, r12, #0, #20
327 // CHECK-ARM-PLT-NEXT
: 1698: ldr pc
, [r12, #576]!
328 // CHECK-ARM-PLT-NEXT
: 169c
: d4 d4 d4 d4
.word 0xd4d4d4d4
329 // CHECK-ARM-PLT-NEXT
: 16a0
: add r12, pc
, #0, #12
330 // CHECK-ARM-PLT-NEXT
: 16a4
: add r12, r12, #0, #20
331 // CHECK-ARM-PLT-NEXT
: 16a8
: ldr pc
, [r12, #564]!
332 // CHECK-ARM-PLT-NEXT
: 16ac
: d4 d4 d4 d4
.word 0xd4d4d4d4
334 // CHECK-DSO-REL
: 0x18C0 R_ARM_JUMP_SLOT thumb_callee1
335 // CHECK-DSO-REL-NEXT
: 0x18C4 R_ARM_JUMP_SLOT arm_callee1
336 // CHECK-DSO-REL-NEXT
: 0x18C8 R_ARM_JUMP_SLOT arm_caller
337 // CHECK-DSO-REL-NEXT
: 0x18CC R_ARM_JUMP_SLOT thumb_callee2
338 // CHECK-DSO-REL-NEXT
: 0x18D0 R_ARM_JUMP_SLOT thumb_callee3
339 // CHECK-DSO-REL-NEXT
: 0x18D4 R_ARM_JUMP_SLOT arm_callee2
340 // CHECK-DSO-REL-NEXT
: 0x18D8 R_ARM_JUMP_SLOT arm_callee3
341 // CHECK-DSO-REL-NEXT
: 0x18DC R_ARM_JUMP_SLOT thumb_caller