[BZ #9881]
[glibc/pb-stable.git] / sysdeps / x86_64 / dl-trampoline.S
blobd8d9bc12a4fd0d10cfa040c4e9b30e10f3c5d755
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 56(%rsp), %rdi     # %rdi: link_map, %rsi: reloc_index
39         call _dl_fixup          # Call resolver.
40         movq %rax, %r11         # Save return value
41         movq 48(%rsp), %r9      # Get register content back.
42         movq 40(%rsp), %r8
43         movq 32(%rsp), %rdi
44         movq 24(%rsp), %rsi
45         movq 16(%rsp), %rdx
46         movq 8(%rsp), %rcx
47         movq (%rsp), %rax
48         addq $72, %rsp          # Adjust stack(PLT did 2 pushes)
49         cfi_adjust_cfa_offset(-72)
50         jmp *%r11               # Jump to function address.
51         cfi_endproc
52         .size _dl_runtime_resolve, .-_dl_runtime_resolve
55 #ifndef PROF
56         .globl _dl_runtime_profile
57         .type _dl_runtime_profile, @function
58         .align 16
59         cfi_startproc
61 _dl_runtime_profile:
62         /* The La_x86_64_regs data structure pointed to by the
63            fourth paramater must be 16-byte aligned.  This must
64            be explicitly enforced.  We have the set up a dynamically
65            sized stack frame.  %rbx points to the top half which
66            has a fixed size and preserves the original stack pointer.  */
68         subq $32, %rsp          # Allocate the local storage.
69         cfi_adjust_cfa_offset(48) # Incorporate PLT
70         movq %rbx, (%rsp)
71         cfi_rel_offset(%rbx, 0)
73         /* On the stack:
74                 56(%rbx)        parameter #1
75                 48(%rbx)        return address
77                 40(%rbx)        reloc index
78                 32(%rbx)        link_map
80                 24(%rbx)        La_x86_64_regs pointer
81                 16(%rbx)        framesize
82                  8(%rbx)        rax
83                   (%rbx)        rbx
84         */
86         movq %rax, 8(%rsp)
87         movq %rsp, %rbx
88         cfi_def_cfa_register(%rbx)
90         /* Actively align the La_x86_64_regs structure.  */
91         andq $0xfffffffffffffff0, %rsp
92         subq $192, %rsp         # sizeof(La_x86_64_regs)
93         movq %rsp, 24(%rbx)
95         movq %rdx,   (%rsp)     # Fill the La_x86_64_regs structure.
96         movq %r8,   8(%rsp)
97         movq %r9,  16(%rsp)
98         movq %rcx, 24(%rsp)
99         movq %rsi, 32(%rsp)
100         movq %rdi, 40(%rsp)
101         movq %rbp, 48(%rsp)
102         leaq 48(%rbx), %rax
103         movq %rax, 56(%rsp)
104         movaps %xmm0,  64(%rsp)
105         movaps %xmm1,  80(%rsp)
106         movaps %xmm2,  96(%rsp)
107         movaps %xmm3, 112(%rsp)
108         movaps %xmm4, 128(%rsp)
109         movaps %xmm5, 144(%rsp)
110         movaps %xmm7, 160(%rsp)
112         movq %rsp, %rcx         # La_x86_64_regs pointer to %rcx.
113         movq 48(%rbx), %rdx     # Load return address if needed.
114         movq 40(%rbx), %rsi     # Copy args pushed by PLT in register.
115         movq 32(%rbx), %rdi     # %rdi: link_map, %rsi: reloc_index
116         leaq 16(%rbx), %r8
117         call _dl_profile_fixup  # Call resolver.
119         movq %rax, %r11         # Save return value.
121         movq 8(%rbx), %rax      # Get back register content.
122         movq      (%rsp), %rdx
123         movq     8(%rsp), %r8
124         movq    16(%rsp), %r9
125         movaps  64(%rsp), %xmm0
126         movaps  80(%rsp), %xmm1
127         movaps  96(%rsp), %xmm2
128         movaps 112(%rsp), %xmm3
129         movaps 128(%rsp), %xmm4
130         movaps 144(%rsp), %xmm5
131         movaps 160(%rsp), %xmm7
133         movq 16(%rbx), %r10     # Anything in framesize?
134         testq %r10, %r10
135         jns 1f
137         /* There's nothing in the frame size, so there
138            will be no call to the _dl_call_pltexit. */
140         movq 24(%rsp), %rcx     # Get back registers content.
141         movq 32(%rsp), %rsi
142         movq 40(%rsp), %rdi
144         movq %rbx, %rsp
145         movq (%rsp), %rbx
146         cfi_restore(rbx)
147         cfi_def_cfa_register(%rsp)
149         addq $48, %rsp          # Adjust the stack to the return value
150                                 # (eats the reloc index and link_map)
151         cfi_adjust_cfa_offset(-48)
152         jmp *%r11               # Jump to function address.
155         cfi_adjust_cfa_offset(48)
156         cfi_rel_offset(%rbx, 0)
157         cfi_def_cfa_register(%rbx)
159         /* At this point we need to prepare new stack for the function
160            which has to be called.  We copy the original stack to a
161            temporary buffer of the size specified by the 'framesize'
162            returned from _dl_profile_fixup */
164         leaq 56(%rbx), %rsi     # stack
165         addq $8, %r10
166         andq $0xfffffffffffffff0, %r10
167         movq %r10, %rcx
168         subq %r10, %rsp
169         movq %rsp, %rdi
170         shrq $3, %rcx
171         rep
172         movsq
174         movq 24(%rdi), %rcx     # Get back register content.
175         movq 32(%rdi), %rsi
176         movq 40(%rdi), %rdi
178         call *%r11
180         mov 24(%rbx), %rsp      # Drop the copied stack content
182         /* Now we have to prepare the La_x86_64_retval structure for the
183            _dl_call_pltexit.  The La_x86_64_regs is being pointed by rsp now,
184            so we just need to allocate the sizeof(La_x86_64_retval) space on
185            the stack, since the alignment has already been taken care of. */
187         subq $80, %rsp          # sizeof(La_x86_64_retval)
188         movq %rsp, %rcx         # La_x86_64_retval argument to %rcx.
190         movq %rax, (%rcx)       # Fill in the La_x86_64_retval structure.
191         movq %rdx, 8(%rcx)
192         movaps %xmm0, 16(%rcx)
193         movaps %xmm1, 32(%rcx)
194         fstpt 48(%rcx)
195         fstpt 64(%rcx)
197         movq 24(%rbx), %rdx     # La_x86_64_regs argument to %rdx.
198         movq 40(%rbx), %rsi     # Copy args pushed by PLT in register.
199         movq 32(%rbx), %rdi     # %rdi: link_map, %rsi: reloc_index
200         call _dl_call_pltexit
202         movq  (%rsp), %rax      # Restore return registers.
203         movq 8(%rsp), %rdx
204         movaps 16(%rsp), %xmm0
205         movaps 32(%rsp), %xmm1
206         fldt 64(%rsp)
207         fldt 48(%rsp)
209         movq %rbx, %rsp
210         movq  (%rsp), %rbx
211         cfi_restore(rbx)
212         cfi_def_cfa_register(%rsp)
214         addq $48, %rsp          # Adjust the stack to the return value
215                                 # (eats the reloc index and link_map)
216         cfi_adjust_cfa_offset(-48)
217         retq
219         cfi_endproc
220         .size _dl_runtime_profile, .-_dl_runtime_profile
221 #endif