// REQUIRES: aarch64 // RUN: split-file %s %t // RUN: llvm-mc -filetype=obj -triple=aarch64 %t/asm -o %t.o // RUN: ld.lld --script %t/lds --shared %t.o -o %t.so 2>&1 // RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t.so | FileCheck %s // Check that Position Independent thunks are generated for shared libraries. //--- asm .section .text_low, "ax", %progbits .globl low_target .type low_target, %function low_target: // Need thunk to high_target@plt bl high_target ret // CHECK: : // CHECK-NEXT: d8: bl 0xec <__AArch64ADRPThunk_high_target> // CHECK-NEXT: ret .hidden low_target2 .globl low_target2 .type low_target2, %function low_target2: // Need thunk to high_target2 bl high_target2 // .text_high+8 = high_target2 bl .text_high+8 ret // CHECK: : // CHECK-NEXT: e0: bl 0xf8 <__AArch64ADRPThunk_high_target2> // CHECK-NEXT: e4: bl 0x104 <__AArch64ADRPThunk_> // CHECK-NEXT: ret // Expect range extension thunks for .text_low // adrp calculation is (PC + signed immediate) & (!0xfff) // CHECK: <__AArch64ADRPThunk_high_target>: // CHECK-NEXT: ec: adrp x16, #0x10000000 // CHECK-NEXT: add x16, x16, #0x40 // CHECK-NEXT: br x16 // CHECK: <__AArch64ADRPThunk_high_target2>: // CHECK-NEXT: f8: adrp x16, #0x10000000 // CHECK-NEXT: add x16, x16, #0x8 // CHECK-NEXT: br x16 /// Identical to the previous one, but for the target .text_high+8. // CHECK: <__AArch64ADRPThunk_>: // CHECK-NEXT: 104: adrp x16, #0x10000000 // CHECK-NEXT: add x16, x16, #0x8 // CHECK-NEXT: br x16 .section .text_high, "ax", %progbits .globl high_target .type high_target, %function high_target: // No thunk needed as we can reach low_target@plt bl low_target ret // CHECK: : // CHECK-NEXT: 10000000: bl 0x10000050 // CHECK-NEXT: ret .hidden high_target2 .globl high_target2 .type high_target2, %function high_target2: // Need thunk to low_target bl low_target2 ret // CHECK: : // CHECK-NEXT: 10000008: bl 0x10000010 <__AArch64ADRPThunk_low_target2> // CHECK-NEXT: ret // Expect Thunk for .text.high // CHECK: <__AArch64ADRPThunk_low_target2>: // CHECK-NEXT: 10000010: adrp x16, #-0x10000000 // CHECK-NEXT: add x16, x16, #0xe0 // CHECK-NEXT: br x16 // CHECK: Disassembly of section .plt: // CHECK-EMPTY: // CHECK-NEXT: <.plt>: // CHECK-NEXT: 10000020: stp x16, x30, [sp, #-0x10]! // CHECK-NEXT: adrp x16, #0 // CHECK-NEXT: ldr x17, [x16, #0x120] // CHECK-NEXT: add x16, x16, #0x120 // CHECK-NEXT: br x17 // CHECK-NEXT: nop // CHECK-NEXT: nop // CHECK-NEXT: nop // CHECK-EMPTY: // CHECK-NEXT: : // CHECK-NEXT: 10000040: adrp x16, #0x0 // CHECK-NEXT: ldr x17, [x16, #0x128] // CHECK-NEXT: add x16, x16, #0x128 // CHECK-NEXT: br x17 // CHECK-EMPTY: // CHECK-NEXT: : // CHECK-NEXT: 10000050: adrp x16, #0x0 // CHECK-NEXT: ldr x17, [x16, #0x130] // CHECK-NEXT: add x16, x16, #0x130 // CHECK-NEXT: br x17 //--- lds PHDRS { low PT_LOAD FLAGS(0x1 | 0x4); high PT_LOAD FLAGS(0x1 | 0x4); } SECTIONS { .text_low : { *(.text_low) } :low .text_high 0x10000000 : { *(.text_high) } :high }