[BZ #9893]
[glibc.git] / sysdeps / x86_64 / dl-trampoline.S
blobc9be759e3759d1a0750a2e9358e9fad82468f623
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 <sysdep.h>
22         .text
23         .globl _dl_runtime_resolve
24         .type _dl_runtime_resolve, @function
25         .align 16
26         cfi_startproc
27 _dl_runtime_resolve:
28         subq $56,%rsp
29         cfi_adjust_cfa_offset(72) # Incorporate PLT
30         movq %rax,(%rsp)        # Preserve registers otherwise clobbered.
31         movq %rcx, 8(%rsp)
32         movq %rdx, 16(%rsp)
33         movq %rsi, 24(%rsp)
34         movq %rdi, 32(%rsp)
35         movq %r8, 40(%rsp)
36         movq %r9, 48(%rsp)
37         movq 64(%rsp), %rsi     # Copy args pushed by PLT in register.
38         movq %rsi, %r11         # Multiply by 24
39         addq %r11, %rsi
40         addq %r11, %rsi
41         shlq $3, %rsi
42         movq 56(%rsp), %rdi     # %rdi: link_map, %rsi: reloc_offset
43         call _dl_fixup          # Call resolver.
44         movq %rax, %r11         # Save return value
45         movq 48(%rsp), %r9      # Get register content back.
46         movq 40(%rsp), %r8
47         movq 32(%rsp), %rdi
48         movq 24(%rsp), %rsi
49         movq 16(%rsp), %rdx
50         movq 8(%rsp), %rcx
51         movq (%rsp), %rax
52         addq $72, %rsp          # Adjust stack(PLT did 2 pushes)
53         cfi_adjust_cfa_offset(-72)
54         jmp *%r11               # Jump to function address.
55         cfi_endproc
56         .size _dl_runtime_resolve, .-_dl_runtime_resolve
59 #ifndef PROF
60         .globl _dl_runtime_profile
61         .type _dl_runtime_profile, @function
62         .align 16
63         cfi_startproc
65 _dl_runtime_profile:
66         /* The La_x86_64_regs data structure pointed to by the
67            fourth paramater must be 16-byte aligned.  This must
68            be explicitly enforced.  We have the set up a dynamically
69            sized stack frame.  %rbx points to the top half which
70            has a fixed size and preserves the original stack pointer.  */
72         subq $32, %rsp          # Allocate the local storage.
73         cfi_adjust_cfa_offset(48) # Incorporate PLT
74         movq %rbx, (%rsp)
75         cfi_rel_offset(%rbx, 0)
77         /* On the stack:
78                 56(%rbx)        parameter #1
79                 48(%rbx)        return address
81                 40(%rbx)        reloc index
82                 32(%rbx)        link_map
84                 24(%rbx)        La_x86_64_regs pointer
85                 16(%rbx)        framesize
86                  8(%rbx)        rax
87                   (%rbx)        rbx
88         */
90         movq %rax, 8(%rsp)
91         movq %rsp, %rbx
92         cfi_def_cfa_register(%rbx)
94         /* Actively align the La_x86_64_regs structure.  */
95         andq $0xfffffffffffffff0, %rsp
96         subq $192, %rsp         # sizeof(La_x86_64_regs)
97         movq %rsp, 24(%rbx)
99         movq %rdx,   (%rsp)     # Fill the La_x86_64_regs structure.
100         movq %r8,   8(%rsp)
101         movq %r9,  16(%rsp)
102         movq %rcx, 24(%rsp)
103         movq %rsi, 32(%rsp)
104         movq %rdi, 40(%rsp)
105         movq %rbp, 48(%rsp)
106         leaq 48(%rbx), %rax
107         movq %rax, 56(%rsp)
108         movaps %xmm0,  64(%rsp)
109         movaps %xmm1,  80(%rsp)
110         movaps %xmm2,  96(%rsp)
111         movaps %xmm3, 112(%rsp)
112         movaps %xmm4, 128(%rsp)
113         movaps %xmm5, 144(%rsp)
114         movaps %xmm7, 160(%rsp)
116         movq %rsp, %rcx         # La_x86_64_regs pointer to %rcx.
117         movq 48(%rbx), %rdx     # Load return address if needed.
118         movq 40(%rbx), %rsi     # Copy args pushed by PLT in register.
119         movq %rsi,%r11          # Multiply by 24.
120         addq %r11,%rsi
121         addq %r11,%rsi
122         shlq $3, %rsi
123         movq 32(%rbx), %rdi     # %rdi: link_map, %rsi: reloc_offset
124         leaq 16(%rbx), %r8
125         call _dl_profile_fixup  # Call resolver.
127         movq %rax, %r11         # Save return value.
129         movq 8(%rbx), %rax      # Get back register content.
130         movq      (%rsp), %rdx
131         movq     8(%rsp), %r8
132         movq    16(%rsp), %r9
133         movaps  64(%rsp), %xmm0
134         movaps  80(%rsp), %xmm1
135         movaps  96(%rsp), %xmm2
136         movaps 112(%rsp), %xmm3
137         movaps 128(%rsp), %xmm4
138         movaps 144(%rsp), %xmm5
139         movaps 160(%rsp), %xmm7
141         movq 16(%rbx), %r10     # Anything in framesize?
142         testq %r10, %r10
143         jns 1f
145         /* There's nothing in the frame size, so there
146            will be no call to the _dl_call_pltexit. */
148         movq 24(%rsp), %rcx     # Get back registers content.
149         movq 32(%rsp), %rsi
150         movq 40(%rsp), %rdi
152         movq %rbx, %rsp
153         movq (%rsp), %rbx
154         cfi_restore(rbx)
155         cfi_def_cfa_register(%rsp)
157         addq $48, %rsp          # Adjust the stack to the return value
158                                 # (eats the reloc index and link_map)
159         cfi_adjust_cfa_offset(-48)
160         jmp *%r11               # Jump to function address.
163         cfi_adjust_cfa_offset(48)
164         cfi_rel_offset(%rbx, 0)
165         cfi_def_cfa_register(%rbx)
167         /* At this point we need to prepare new stack for the function
168            which has to be called.  We copy the original stack to a
169            temporary buffer of the size specified by the 'framesize'
170            returned from _dl_profile_fixup */
172         leaq 56(%rbx), %rsi     # stack
173         addq $8, %r10
174         andq $0xfffffffffffffff0, %r10
175         movq %r10, %rcx
176         subq %r10, %rsp
177         movq %rsp, %rdi
178         shrq $3, %rcx
179         rep
180         movsq
182         movq 24(%rdi), %rcx     # Get back register content.
183         movq 32(%rdi), %rsi
184         movq 40(%rdi), %rdi
186         call *%r11
188         mov 24(%rbx), %rsp      # Drop the copied stack content
190         /* Now we have to prepare the La_x86_64_retval structure for the
191            _dl_call_pltexit.  The La_x86_64_regs is being pointed by rsp now,
192            so we just need to allocate the sizeof(La_x86_64_retval) space on
193            the stack, since the alignment has already been taken care of. */
195         subq $80, %rsp          # sizeof(La_x86_64_retval)
196         movq %rsp, %rcx         # La_x86_64_retval argument to %rcx.
198         movq %rax, (%rcx)       # Fill in the La_x86_64_retval structure.
199         movq %rdx, 8(%rcx)
200         movaps %xmm0, 16(%rcx)
201         movaps %xmm1, 32(%rcx)
202         fstpt 48(%rcx)
203         fstpt 64(%rcx)
205         movq 24(%rbx), %rdx     # La_x86_64_regs argument to %rdx.
206         movq 40(%rbx), %rsi     # Copy args pushed by PLT in register.
207         movq %rsi,%r11          # Multiply by 24.
208         addq %r11,%rsi
209         addq %r11,%rsi
210         shlq $3, %rsi
211         movq 32(%rbx), %rdi     # %rdi: link_map, %rsi: reloc_offset
212         call _dl_call_pltexit
214         movq  (%rsp), %rax      # Restore return registers.
215         movq 8(%rsp), %rdx
216         movaps 16(%rsp), %xmm0
217         movaps 32(%rsp), %xmm1
218         fldt 64(%rsp)
219         fldt 48(%rsp)
221         movq %rbx, %rsp
222         movq  (%rsp), %rbx
223         cfi_restore(rbx)
224         cfi_def_cfa_register(%rsp)
226         addq $48, %rsp          # Adjust the stack to the return value
227                                 # (eats the reloc index and link_map)
228         cfi_adjust_cfa_offset(-48)
229         retq
231         cfi_endproc
232         .size _dl_runtime_profile, .-_dl_runtime_profile
233 #endif