xref: /llvm-project/lld/test/ELF/aarch64-thunk-pi.s (revision cf783be8d7a8594ab82f8215671dddbebcae39ec)
1// REQUIRES: aarch64
2// RUN: split-file %s %t
3// RUN: llvm-mc -filetype=obj -triple=aarch64 %t/asm -o %t.o
4// RUN: ld.lld --script %t/lds --shared %t.o -o %t.so 2>&1
5// RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t.so | FileCheck %s
6
7// Check that Position Independent thunks are generated for shared libraries.
8
9//--- asm
10 .section .text_low, "ax", %progbits
11 .globl low_target
12 .type low_target, %function
13low_target:
14 // Need thunk to high_target@plt
15 bl high_target
16 ret
17// CHECK: <low_target>:
18// CHECK-NEXT:        0:       bl      0x14 <__AArch64ADRPThunk_high_target>
19// CHECK-NEXT:                 ret
20
21 .hidden low_target2
22 .globl low_target2
23 .type low_target2, %function
24low_target2:
25 // Need thunk to high_target2
26 bl high_target2
27 // .text_high+8 = high_target2
28 bl .text_high+8
29 ret
30// CHECK: <low_target2>:
31// CHECK-NEXT:        8:       bl      0x20 <__AArch64ADRPThunk_high_target2>
32// CHECK-NEXT:        c:       bl      0x2c <__AArch64ADRPThunk_>
33// CHECK-NEXT:                 ret
34
35// Expect range extension thunks for .text_low
36// adrp calculation is (PC + signed immediate) & (!0xfff)
37// CHECK: <__AArch64ADRPThunk_high_target>:
38// CHECK-NEXT:       14:       adrp    x16, 0x10000000
39// CHECK-NEXT:                 add     x16, x16, #0x50
40// CHECK-NEXT:                 br      x16
41// CHECK: <__AArch64ADRPThunk_high_target2>:
42// CHECK-NEXT:       20:       adrp    x16, 0x10000000
43// CHECK-NEXT:                 add     x16, x16, #0x8
44// CHECK-NEXT:                 br      x16
45/// Identical to the previous one, but for the target .text_high+8.
46// CHECK: <__AArch64ADRPThunk_>:
47// CHECK-NEXT:       2c:       adrp    x16, 0x10000000
48// CHECK-NEXT:                 add     x16, x16, #0x8
49// CHECK-NEXT:                 br      x16
50
51
52 .section .text_high, "ax", %progbits
53 .globl high_target
54 .type high_target, %function
55high_target:
56 // No thunk needed as we can reach low_target@plt
57 bl low_target
58 ret
59// CHECK: <high_target>:
60// CHECK-NEXT: 10000000:       bl 0x10000040 <low_target@plt>
61// CHECK-NEXT:                 ret
62
63 .hidden high_target2
64 .globl high_target2
65 .type high_target2, %function
66high_target2:
67 // Need thunk to low_target
68 bl low_target2
69 ret
70// CHECK: <high_target2>:
71// CHECK-NEXT: 10000008:       bl      0x10000010 <__AArch64ADRPThunk_low_target2>
72// CHECK-NEXT:                 ret
73
74// Expect Thunk for .text.high
75
76// CHECK: <__AArch64ADRPThunk_low_target2>:
77// CHECK-NEXT: 10000010:       adrp    x16, 0x0
78// CHECK-NEXT:                 add     x16, x16, #0x8
79// CHECK-NEXT:                 br      x16
80
81// CHECK: Disassembly of section .plt:
82// CHECK-EMPTY:
83// CHECK-NEXT: <.plt>:
84// CHECK-NEXT: 10000020:       stp     x16, x30, [sp, #-0x10]!
85// CHECK-NEXT:                 adrp    x16, 0x10000000
86// CHECK-NEXT:                 ldr     x17, [x16, #0x1f8]
87// CHECK-NEXT:                 add     x16, x16, #0x1f8
88// CHECK-NEXT:                 br      x17
89// CHECK-NEXT:                 nop
90// CHECK-NEXT:                 nop
91// CHECK-NEXT:                 nop
92// CHECK-EMPTY:
93// CHECK-NEXT:   <low_target@plt>:
94// CHECK-NEXT: 10000040:       adrp    x16, 0x10000000
95// CHECK-NEXT:                 ldr     x17, [x16, #0x200]
96// CHECK-NEXT:                 add     x16, x16, #0x200
97// CHECK-NEXT:                 br      x17
98// CHECK-EMPTY:
99// CHECK-NEXT:   <high_target@plt>:
100// CHECK-NEXT: 10000050:       adrp    x16, 0x10000000
101// CHECK-NEXT:                 ldr     x17, [x16, #0x208]
102// CHECK-NEXT:                 add     x16, x16, #0x208
103// CHECK-NEXT:                 br      x17
104
105//--- lds
106PHDRS {
107  low PT_LOAD FLAGS(0x1 | 0x4);
108  high PT_LOAD FLAGS(0x1 | 0x4);
109}
110SECTIONS {
111  .text_low : { *(.text_low) } :low
112  .text_high 0x10000000 : { *(.text_high) } :high
113}
114