| // This file is generated from a similarly-named Perl script in the BoringSSL |
| // source tree. Do not edit by hand. |
| |
| #include <openssl/asm_base.h> |
| |
| #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__ELF__) |
| .text |
| |
| // abi_test_trampoline loads callee-saved registers from |state|, calls |func| |
| // with |argv|, then saves the callee-saved registers into |state|. It returns |
| // the result of |func|. If |unwind| is non-zero, this function triggers unwind |
| // instrumentation. |
| // uint64_t abi_test_trampoline(void (*func)(...), CallerState *state, |
| // const uint64_t *argv, size_t argc, |
| // int unwind); |
| .globl abi_test_trampoline |
| .hidden abi_test_trampoline |
| .type abi_test_trampoline, @function |
| .align 16 |
| abi_test_trampoline: |
| .cfi_startproc |
| |
| _CET_ENDBR |
| // Stack layout: |
| // 8 bytes - align |
| // 48 bytes - saved caller registers |
| // 8 bytes - scratch space |
| // 8 bytes - saved copy of $unwind (SysV-only) |
| // 8 bytes - saved copy of $state |
| // 8 bytes - saved copy of $func |
| // 8 bytes - if needed for stack alignment |
| // 8*4 bytes - parameters for $func |
| subq $120,%rsp |
| .cfi_adjust_cfa_offset 120 |
| |
| movq %r8,48(%rsp) |
| movq %rbx,64(%rsp) |
| .cfi_offset rbx, -64 |
| |
| movq %rbp,72(%rsp) |
| .cfi_offset rbp, -56 |
| |
| movq %r12,80(%rsp) |
| .cfi_offset r12, -48 |
| |
| movq %r13,88(%rsp) |
| .cfi_offset r13, -40 |
| |
| movq %r14,96(%rsp) |
| .cfi_offset r14, -32 |
| |
| movq %r15,104(%rsp) |
| .cfi_offset r15, -24 |
| |
| |
| movq 0(%rsi),%rbx |
| movq 8(%rsi),%rbp |
| movq 16(%rsi),%r12 |
| movq 24(%rsi),%r13 |
| movq 32(%rsi),%r14 |
| movq 40(%rsi),%r15 |
| // Stash $func and $state, so they are available after the call returns. |
| movq %rdi,32(%rsp) |
| movq %rsi,40(%rsp) |
| |
| // Load parameters. Note this will clobber $argv and $argc, so we can |
| // only use non-parameter volatile registers. There are three, and they |
| // are the same between SysV and Win64: %rax, %r10, and %r11. |
| movq %rdx,%r10 |
| movq %rcx,%r11 |
| decq %r11 |
| js .Largs_done |
| movq (%r10),%rdi |
| addq $8,%r10 |
| decq %r11 |
| js .Largs_done |
| movq (%r10),%rsi |
| addq $8,%r10 |
| decq %r11 |
| js .Largs_done |
| movq (%r10),%rdx |
| addq $8,%r10 |
| decq %r11 |
| js .Largs_done |
| movq (%r10),%rcx |
| addq $8,%r10 |
| decq %r11 |
| js .Largs_done |
| movq (%r10),%r8 |
| addq $8,%r10 |
| decq %r11 |
| js .Largs_done |
| movq (%r10),%r9 |
| addq $8,%r10 |
| leaq 0(%rsp),%rax |
| .Largs_loop: |
| decq %r11 |
| js .Largs_done |
| |
| // This block should be: |
| // movq (%r10), %rtmp |
| // movq %rtmp, (%rax) |
| // There are no spare registers available, so we spill into the scratch |
| // space. |
| movq %r11,56(%rsp) |
| movq (%r10),%r11 |
| movq %r11,(%rax) |
| movq 56(%rsp),%r11 |
| |
| addq $8,%r10 |
| addq $8,%rax |
| jmp .Largs_loop |
| |
| .Largs_done: |
| movq 32(%rsp),%rax |
| movq 48(%rsp),%r10 |
| testq %r10,%r10 |
| jz .Lno_unwind |
| |
| // Set the trap flag. |
| pushfq |
| orq $0x100,0(%rsp) |
| popfq |
| |
| // Run an instruction to trigger a breakpoint immediately before the |
| // call. |
| nop |
| .globl abi_test_unwind_start |
| .hidden abi_test_unwind_start |
| abi_test_unwind_start: |
| |
| call *%rax |
| .globl abi_test_unwind_return |
| .hidden abi_test_unwind_return |
| abi_test_unwind_return: |
| |
| // Clear the trap flag. Note this assumes the trap flag was clear on |
| // entry. We do not support instrumenting an unwind-instrumented |
| // |abi_test_trampoline|. |
| pushfq |
| andq $-0x101,0(%rsp) // -0x101 is ~0x100 |
| popfq |
| .globl abi_test_unwind_stop |
| .hidden abi_test_unwind_stop |
| abi_test_unwind_stop: |
| |
| jmp .Lcall_done |
| |
| .Lno_unwind: |
| call *%rax |
| |
| .Lcall_done: |
| // Store what $func did our state, so our caller can check. |
| movq 40(%rsp),%rsi |
| movq %rbx,0(%rsi) |
| movq %rbp,8(%rsi) |
| movq %r12,16(%rsi) |
| movq %r13,24(%rsi) |
| movq %r14,32(%rsi) |
| movq %r15,40(%rsi) |
| movq 64(%rsp),%rbx |
| .cfi_restore rbx |
| movq 72(%rsp),%rbp |
| .cfi_restore rbp |
| movq 80(%rsp),%r12 |
| .cfi_restore r12 |
| movq 88(%rsp),%r13 |
| .cfi_restore r13 |
| movq 96(%rsp),%r14 |
| .cfi_restore r14 |
| movq 104(%rsp),%r15 |
| .cfi_restore r15 |
| addq $120,%rsp |
| .cfi_adjust_cfa_offset -120 |
| |
| // %rax already contains $func's return value, unmodified. |
| ret |
| .cfi_endproc |
| |
| .size abi_test_trampoline,.-abi_test_trampoline |
| .globl abi_test_clobber_rax |
| .hidden abi_test_clobber_rax |
| .type abi_test_clobber_rax, @function |
| .align 16 |
| abi_test_clobber_rax: |
| _CET_ENDBR |
| xorq %rax,%rax |
| ret |
| .size abi_test_clobber_rax,.-abi_test_clobber_rax |
| .globl abi_test_clobber_rbx |
| .hidden abi_test_clobber_rbx |
| .type abi_test_clobber_rbx, @function |
| .align 16 |
| abi_test_clobber_rbx: |
| _CET_ENDBR |
| xorq %rbx,%rbx |
| ret |
| .size abi_test_clobber_rbx,.-abi_test_clobber_rbx |
| .globl abi_test_clobber_rcx |
| .hidden abi_test_clobber_rcx |
| .type abi_test_clobber_rcx, @function |
| .align 16 |
| abi_test_clobber_rcx: |
| _CET_ENDBR |
| xorq %rcx,%rcx |
| ret |
| .size abi_test_clobber_rcx,.-abi_test_clobber_rcx |
| .globl abi_test_clobber_rdx |
| .hidden abi_test_clobber_rdx |
| .type abi_test_clobber_rdx, @function |
| .align 16 |
| abi_test_clobber_rdx: |
| _CET_ENDBR |
| xorq %rdx,%rdx |
| ret |
| .size abi_test_clobber_rdx,.-abi_test_clobber_rdx |
| .globl abi_test_clobber_rdi |
| .hidden abi_test_clobber_rdi |
| .type abi_test_clobber_rdi, @function |
| .align 16 |
| abi_test_clobber_rdi: |
| _CET_ENDBR |
| xorq %rdi,%rdi |
| ret |
| .size abi_test_clobber_rdi,.-abi_test_clobber_rdi |
| .globl abi_test_clobber_rsi |
| .hidden abi_test_clobber_rsi |
| .type abi_test_clobber_rsi, @function |
| .align 16 |
| abi_test_clobber_rsi: |
| _CET_ENDBR |
| xorq %rsi,%rsi |
| ret |
| .size abi_test_clobber_rsi,.-abi_test_clobber_rsi |
| .globl abi_test_clobber_rbp |
| .hidden abi_test_clobber_rbp |
| .type abi_test_clobber_rbp, @function |
| .align 16 |
| abi_test_clobber_rbp: |
| _CET_ENDBR |
| xorq %rbp,%rbp |
| ret |
| .size abi_test_clobber_rbp,.-abi_test_clobber_rbp |
| .globl abi_test_clobber_r8 |
| .hidden abi_test_clobber_r8 |
| .type abi_test_clobber_r8, @function |
| .align 16 |
| abi_test_clobber_r8: |
| _CET_ENDBR |
| xorq %r8,%r8 |
| ret |
| .size abi_test_clobber_r8,.-abi_test_clobber_r8 |
| .globl abi_test_clobber_r9 |
| .hidden abi_test_clobber_r9 |
| .type abi_test_clobber_r9, @function |
| .align 16 |
| abi_test_clobber_r9: |
| _CET_ENDBR |
| xorq %r9,%r9 |
| ret |
| .size abi_test_clobber_r9,.-abi_test_clobber_r9 |
| .globl abi_test_clobber_r10 |
| .hidden abi_test_clobber_r10 |
| .type abi_test_clobber_r10, @function |
| .align 16 |
| abi_test_clobber_r10: |
| _CET_ENDBR |
| xorq %r10,%r10 |
| ret |
| .size abi_test_clobber_r10,.-abi_test_clobber_r10 |
| .globl abi_test_clobber_r11 |
| .hidden abi_test_clobber_r11 |
| .type abi_test_clobber_r11, @function |
| .align 16 |
| abi_test_clobber_r11: |
| _CET_ENDBR |
| xorq %r11,%r11 |
| ret |
| .size abi_test_clobber_r11,.-abi_test_clobber_r11 |
| .globl abi_test_clobber_r12 |
| .hidden abi_test_clobber_r12 |
| .type abi_test_clobber_r12, @function |
| .align 16 |
| abi_test_clobber_r12: |
| _CET_ENDBR |
| xorq %r12,%r12 |
| ret |
| .size abi_test_clobber_r12,.-abi_test_clobber_r12 |
| .globl abi_test_clobber_r13 |
| .hidden abi_test_clobber_r13 |
| .type abi_test_clobber_r13, @function |
| .align 16 |
| abi_test_clobber_r13: |
| _CET_ENDBR |
| xorq %r13,%r13 |
| ret |
| .size abi_test_clobber_r13,.-abi_test_clobber_r13 |
| .globl abi_test_clobber_r14 |
| .hidden abi_test_clobber_r14 |
| .type abi_test_clobber_r14, @function |
| .align 16 |
| abi_test_clobber_r14: |
| _CET_ENDBR |
| xorq %r14,%r14 |
| ret |
| .size abi_test_clobber_r14,.-abi_test_clobber_r14 |
| .globl abi_test_clobber_r15 |
| .hidden abi_test_clobber_r15 |
| .type abi_test_clobber_r15, @function |
| .align 16 |
| abi_test_clobber_r15: |
| _CET_ENDBR |
| xorq %r15,%r15 |
| ret |
| .size abi_test_clobber_r15,.-abi_test_clobber_r15 |
| .globl abi_test_clobber_xmm0 |
| .hidden abi_test_clobber_xmm0 |
| .type abi_test_clobber_xmm0, @function |
| .align 16 |
| abi_test_clobber_xmm0: |
| _CET_ENDBR |
| pxor %xmm0,%xmm0 |
| ret |
| .size abi_test_clobber_xmm0,.-abi_test_clobber_xmm0 |
| .globl abi_test_clobber_xmm1 |
| .hidden abi_test_clobber_xmm1 |
| .type abi_test_clobber_xmm1, @function |
| .align 16 |
| abi_test_clobber_xmm1: |
| _CET_ENDBR |
| pxor %xmm1,%xmm1 |
| ret |
| .size abi_test_clobber_xmm1,.-abi_test_clobber_xmm1 |
| .globl abi_test_clobber_xmm2 |
| .hidden abi_test_clobber_xmm2 |
| .type abi_test_clobber_xmm2, @function |
| .align 16 |
| abi_test_clobber_xmm2: |
| _CET_ENDBR |
| pxor %xmm2,%xmm2 |
| ret |
| .size abi_test_clobber_xmm2,.-abi_test_clobber_xmm2 |
| .globl abi_test_clobber_xmm3 |
| .hidden abi_test_clobber_xmm3 |
| .type abi_test_clobber_xmm3, @function |
| .align 16 |
| abi_test_clobber_xmm3: |
| _CET_ENDBR |
| pxor %xmm3,%xmm3 |
| ret |
| .size abi_test_clobber_xmm3,.-abi_test_clobber_xmm3 |
| .globl abi_test_clobber_xmm4 |
| .hidden abi_test_clobber_xmm4 |
| .type abi_test_clobber_xmm4, @function |
| .align 16 |
| abi_test_clobber_xmm4: |
| _CET_ENDBR |
| pxor %xmm4,%xmm4 |
| ret |
| .size abi_test_clobber_xmm4,.-abi_test_clobber_xmm4 |
| .globl abi_test_clobber_xmm5 |
| .hidden abi_test_clobber_xmm5 |
| .type abi_test_clobber_xmm5, @function |
| .align 16 |
| abi_test_clobber_xmm5: |
| _CET_ENDBR |
| pxor %xmm5,%xmm5 |
| ret |
| .size abi_test_clobber_xmm5,.-abi_test_clobber_xmm5 |
| .globl abi_test_clobber_xmm6 |
| .hidden abi_test_clobber_xmm6 |
| .type abi_test_clobber_xmm6, @function |
| .align 16 |
| abi_test_clobber_xmm6: |
| _CET_ENDBR |
| pxor %xmm6,%xmm6 |
| ret |
| .size abi_test_clobber_xmm6,.-abi_test_clobber_xmm6 |
| .globl abi_test_clobber_xmm7 |
| .hidden abi_test_clobber_xmm7 |
| .type abi_test_clobber_xmm7, @function |
| .align 16 |
| abi_test_clobber_xmm7: |
| _CET_ENDBR |
| pxor %xmm7,%xmm7 |
| ret |
| .size abi_test_clobber_xmm7,.-abi_test_clobber_xmm7 |
| .globl abi_test_clobber_xmm8 |
| .hidden abi_test_clobber_xmm8 |
| .type abi_test_clobber_xmm8, @function |
| .align 16 |
| abi_test_clobber_xmm8: |
| _CET_ENDBR |
| pxor %xmm8,%xmm8 |
| ret |
| .size abi_test_clobber_xmm8,.-abi_test_clobber_xmm8 |
| .globl abi_test_clobber_xmm9 |
| .hidden abi_test_clobber_xmm9 |
| .type abi_test_clobber_xmm9, @function |
| .align 16 |
| abi_test_clobber_xmm9: |
| _CET_ENDBR |
| pxor %xmm9,%xmm9 |
| ret |
| .size abi_test_clobber_xmm9,.-abi_test_clobber_xmm9 |
| .globl abi_test_clobber_xmm10 |
| .hidden abi_test_clobber_xmm10 |
| .type abi_test_clobber_xmm10, @function |
| .align 16 |
| abi_test_clobber_xmm10: |
| _CET_ENDBR |
| pxor %xmm10,%xmm10 |
| ret |
| .size abi_test_clobber_xmm10,.-abi_test_clobber_xmm10 |
| .globl abi_test_clobber_xmm11 |
| .hidden abi_test_clobber_xmm11 |
| .type abi_test_clobber_xmm11, @function |
| .align 16 |
| abi_test_clobber_xmm11: |
| _CET_ENDBR |
| pxor %xmm11,%xmm11 |
| ret |
| .size abi_test_clobber_xmm11,.-abi_test_clobber_xmm11 |
| .globl abi_test_clobber_xmm12 |
| .hidden abi_test_clobber_xmm12 |
| .type abi_test_clobber_xmm12, @function |
| .align 16 |
| abi_test_clobber_xmm12: |
| _CET_ENDBR |
| pxor %xmm12,%xmm12 |
| ret |
| .size abi_test_clobber_xmm12,.-abi_test_clobber_xmm12 |
| .globl abi_test_clobber_xmm13 |
| .hidden abi_test_clobber_xmm13 |
| .type abi_test_clobber_xmm13, @function |
| .align 16 |
| abi_test_clobber_xmm13: |
| _CET_ENDBR |
| pxor %xmm13,%xmm13 |
| ret |
| .size abi_test_clobber_xmm13,.-abi_test_clobber_xmm13 |
| .globl abi_test_clobber_xmm14 |
| .hidden abi_test_clobber_xmm14 |
| .type abi_test_clobber_xmm14, @function |
| .align 16 |
| abi_test_clobber_xmm14: |
| _CET_ENDBR |
| pxor %xmm14,%xmm14 |
| ret |
| .size abi_test_clobber_xmm14,.-abi_test_clobber_xmm14 |
| .globl abi_test_clobber_xmm15 |
| .hidden abi_test_clobber_xmm15 |
| .type abi_test_clobber_xmm15, @function |
| .align 16 |
| abi_test_clobber_xmm15: |
| _CET_ENDBR |
| pxor %xmm15,%xmm15 |
| ret |
| .size abi_test_clobber_xmm15,.-abi_test_clobber_xmm15 |
| // abi_test_bad_unwind_wrong_register preserves the ABI, but annotates the wrong |
| // register in unwind metadata. |
| // void abi_test_bad_unwind_wrong_register(void); |
| .globl abi_test_bad_unwind_wrong_register |
| .hidden abi_test_bad_unwind_wrong_register |
| .type abi_test_bad_unwind_wrong_register, @function |
| .align 16 |
| abi_test_bad_unwind_wrong_register: |
| .cfi_startproc |
| |
| _CET_ENDBR |
| pushq %r12 |
| .cfi_adjust_cfa_offset 8 |
| .cfi_offset %r13,-16 // This should be %r13 |
| // This should be %r13 |
| |
| // Windows evaluates epilogs directly in the unwinder, rather than using |
| // unwind codes. Add a nop so there is one non-epilog point (immediately |
| // before the nop) where the unwinder can observe the mistake. |
| nop |
| popq %r12 |
| .cfi_adjust_cfa_offset -8 |
| .cfi_restore %r12 |
| ret |
| |
| .cfi_endproc |
| .size abi_test_bad_unwind_wrong_register,.-abi_test_bad_unwind_wrong_register |
| |
| // abi_test_bad_unwind_temporary preserves the ABI, but temporarily corrupts the |
| // storage space for a saved register, breaking unwind. |
| // void abi_test_bad_unwind_temporary(void); |
| .globl abi_test_bad_unwind_temporary |
| .hidden abi_test_bad_unwind_temporary |
| .type abi_test_bad_unwind_temporary, @function |
| .align 16 |
| abi_test_bad_unwind_temporary: |
| .cfi_startproc |
| |
| _CET_ENDBR |
| pushq %r12 |
| .cfi_adjust_cfa_offset 8 |
| .cfi_offset %r12,-16 |
| |
| |
| |
| movq %r12,%rax |
| incq %rax |
| movq %rax,(%rsp) |
| // Unwinding from here is incorrect. Although %r12 itself has not been |
| // changed, the unwind codes say to look in (%rsp) instead. |
| |
| movq %r12,(%rsp) |
| // Unwinding is now fixed. |
| |
| popq %r12 |
| .cfi_adjust_cfa_offset -8 |
| .cfi_restore %r12 |
| ret |
| .cfi_endproc |
| |
| .size abi_test_bad_unwind_temporary,.-abi_test_bad_unwind_temporary |
| |
| // abi_test_get_and_clear_direction_flag clears the direction flag. If the flag |
| // was previously set, it returns one. Otherwise, it returns zero. |
| // int abi_test_get_and_clear_direction_flag(void); |
| .globl abi_test_get_and_clear_direction_flag |
| .hidden abi_test_get_and_clear_direction_flag |
| .type abi_test_get_and_clear_direction_flag, @function |
| abi_test_get_and_clear_direction_flag: |
| _CET_ENDBR |
| pushfq |
| popq %rax |
| andq $0x400,%rax |
| shrq $10,%rax |
| cld |
| ret |
| .size abi_test_get_and_clear_direction_flag,.-abi_test_get_and_clear_direction_flag |
| |
| // abi_test_set_direction_flag sets the direction flag. |
| // void abi_test_set_direction_flag(void); |
| .globl abi_test_set_direction_flag |
| .hidden abi_test_set_direction_flag |
| .type abi_test_set_direction_flag, @function |
| abi_test_set_direction_flag: |
| _CET_ENDBR |
| std |
| ret |
| .size abi_test_set_direction_flag,.-abi_test_set_direction_flag |
| #endif |