/* * Copyright 2018-2025 Yury Gribov * * The MIT License (MIT) * * Use of this source code is governed by MIT license that can be * found in the LICENSE.txt file. */ #define lr x30 #define ip0 x16 .section .note.GNU-stack,"",@progbits .data .globl _${lib_suffix}_tramp_table .hidden _${lib_suffix}_tramp_table .align 8 _${lib_suffix}_tramp_table: .zero $table_size .text .globl _${lib_suffix}_tramp_resolve .hidden _${lib_suffix}_tramp_resolve .globl _${lib_suffix}_save_regs_and_resolve .hidden _${lib_suffix}_save_regs_and_resolve .type _${lib_suffix}_save_regs_and_resolve, %function _${lib_suffix}_save_regs_and_resolve: .cfi_startproc // Slow path which calls dlsym, taken only on first call. // Registers are saved according to "Procedure Call Standard for the ArmĀ® 64-bit Architecture". // For DWARF directives, read https://www.imperialviolet.org/2017/01/18/cfi.html. // Stack is aligned at 16 bytes #define PUSH_PAIR(reg1, reg2) stp reg1, reg2, [sp, #-16]!; .cfi_adjust_cfa_offset 16; .cfi_rel_offset reg1, 0; .cfi_rel_offset reg2, 8 #define POP_PAIR(reg1, reg2) ldp reg1, reg2, [sp], #16; .cfi_adjust_cfa_offset -16; .cfi_restore reg2; .cfi_restore reg1 #define PUSH_WIDE_PAIR(reg1, reg2) stp reg1, reg2, [sp, #-32]!; .cfi_adjust_cfa_offset 32; .cfi_rel_offset reg1, 0; .cfi_rel_offset reg2, 16 #define POP_WIDE_PAIR(reg1, reg2) ldp reg1, reg2, [sp], #32; .cfi_adjust_cfa_offset -32; .cfi_restore reg2; .cfi_restore reg1 // Save only arguments (and lr) PUSH_PAIR(x0, x1) PUSH_PAIR(x2, x3) PUSH_PAIR(x4, x5) PUSH_PAIR(x6, x7) PUSH_PAIR(x8, lr) ldr x0, [sp, #80] // 16*5 PUSH_WIDE_PAIR(q0, q1) PUSH_WIDE_PAIR(q2, q3) PUSH_WIDE_PAIR(q4, q5) PUSH_WIDE_PAIR(q6, q7) // Stack is aligned at 16 bytes bl _${lib_suffix}_tramp_resolve mov ip0, x0 // TODO: pop pc? POP_WIDE_PAIR(q6, q7) POP_WIDE_PAIR(q4, q5) POP_WIDE_PAIR(q2, q3) POP_WIDE_PAIR(q0, q1) POP_PAIR(x8, lr) POP_PAIR(x6, x7) POP_PAIR(x4, x5) POP_PAIR(x2, x3) POP_PAIR(x0, x1) br lr .cfi_endproc