Add AVX support to ld.so auditing for x86-64.
[glibc.git] / sysdeps / x86_64 / dl-trampoline.S
blobf605351f3095be3203913de8a237c7c93de9cc9a
1 /* PLT trampolines.  x86-64 version.
2    Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <config.h>
21 #include <sysdep.h>
22 #include <link-defines.h>
24         .text
25         .globl _dl_runtime_resolve
26         .type _dl_runtime_resolve, @function
27         .align 16
28         cfi_startproc
29 _dl_runtime_resolve:
30         subq $56,%rsp
31         cfi_adjust_cfa_offset(72) # Incorporate PLT
32         movq %rax,(%rsp)        # Preserve registers otherwise clobbered.
33         movq %rcx, 8(%rsp)
34         movq %rdx, 16(%rsp)
35         movq %rsi, 24(%rsp)
36         movq %rdi, 32(%rsp)
37         movq %r8, 40(%rsp)
38         movq %r9, 48(%rsp)
39         movq 64(%rsp), %rsi     # Copy args pushed by PLT in register.
40         movq 56(%rsp), %rdi     # %rdi: link_map, %rsi: reloc_index
41         call _dl_fixup          # Call resolver.
42         movq %rax, %r11         # Save return value
43         movq 48(%rsp), %r9      # Get register content back.
44         movq 40(%rsp), %r8
45         movq 32(%rsp), %rdi
46         movq 24(%rsp), %rsi
47         movq 16(%rsp), %rdx
48         movq 8(%rsp), %rcx
49         movq (%rsp), %rax
50         addq $72, %rsp          # Adjust stack(PLT did 2 pushes)
51         cfi_adjust_cfa_offset(-72)
52         jmp *%r11               # Jump to function address.
53         cfi_endproc
54         .size _dl_runtime_resolve, .-_dl_runtime_resolve
57 #ifndef PROF
58         .globl _dl_runtime_profile
59         .type _dl_runtime_profile, @function
60         .align 16
61         cfi_startproc
63 _dl_runtime_profile:
64         /* The La_x86_64_regs data structure pointed to by the
65            fourth paramater must be 16-byte aligned.  This must
66            be explicitly enforced.  We have the set up a dynamically
67            sized stack frame.  %rbx points to the top half which
68            has a fixed size and preserves the original stack pointer.  */
70         subq $32, %rsp          # Allocate the local storage.
71         cfi_adjust_cfa_offset(48) # Incorporate PLT
72         movq %rbx, (%rsp)
73         cfi_rel_offset(%rbx, 0)
75         /* On the stack:
76                 56(%rbx)        parameter #1
77                 48(%rbx)        return address
79                 40(%rbx)        reloc index
80                 32(%rbx)        link_map
82                 24(%rbx)        La_x86_64_regs pointer
83                 16(%rbx)        framesize
84                  8(%rbx)        rax
85                   (%rbx)        rbx
86         */
88         movq %rax, 8(%rsp)
89         movq %rsp, %rbx
90         cfi_def_cfa_register(%rbx)
92         /* Actively align the La_x86_64_regs structure.  */
93         andq $0xfffffffffffffff0, %rsp
94 # ifdef HAVE_AVX_SUPPORT
95         /* sizeof(La_x86_64_regs).  Need extra space for 8 SSE registers
96            to detect if any xmm0-xmm7 registers are changed by audit
97            module.  */
98         subq $(LR_SIZE + XMM_SIZE*8), %rsp
99 #else
100         subq $LR_SIZE, %rsp             # sizeof(La_x86_64_regs)
101 #endif
102         movq %rsp, 24(%rbx)
104         /* Fill the La_x86_64_regs structure.  */
105         movq %rdx, LR_RDX_OFFSET(%rsp)
106         movq %r8,  LR_R8_OFFSET(%rsp)
107         movq %r9,  LR_R9_OFFSET(%rsp)
108         movq %rcx, LR_RCX_OFFSET(%rsp)
109         movq %rsi, LR_RSI_OFFSET(%rsp)
110         movq %rdi, LR_RDI_OFFSET(%rsp)
111         movq %rbp, LR_RBP_OFFSET(%rsp)
113 # ifdef HAVE_AVX_SUPPORT
114         jmp *L(save_and_restore_vector)(%rip)
116         .align 16
117 L(save_and_restore_vector_sse):
118 # endif
120 # define MOVXMM movaps
121 # include "dl-trampoline.h"
123 # ifdef HAVE_AVX_SUPPORT
124 #  undef  MOVXMM
125 #  define MOVXMM vmovdqa
126 #  define RESTORE_AVX
127         .align 16
128 L(save_and_restore_vector_avx):
129 #  include "dl-trampoline.h"
130 # endif
132         cfi_endproc
133         .size _dl_runtime_profile, .-_dl_runtime_profile
135 # ifdef HAVE_AVX_SUPPORT
136 L(check_avx):
137         mov     %rbx,%r11               # Save rbx
138         movl    $1, %eax
139         cpuid
140         mov     %r11,%rbx               # Restore rbx
141         leaq    L(save_and_restore_vector_sse)(%rip), %rax
142         andl    $(1 << 28), %ecx        # Check if AVX is available.
143         jz      L(ret)
144         leaq    L(save_and_restore_vector_avx)(%rip), %rax
145 L(ret):
146         movq    %rax,L(save_and_restore_vector)(%rip)
147         jmp     *%rax
149         .section .data.rel.local,"aw",@progbits
150         .align  8
151 L(save_and_restore_vector):
152         .quad L(check_avx)
153 # endif
154 #endif