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
23 .globl _dl_runtime_resolve
24 .type _dl_runtime_resolve, @function
29 cfi_adjust_cfa_offset(72) # Incorporate PLT
30 movq %rax,(%rsp) # Preserve registers otherwise clobbered.
37 movq 64(%rsp), %rsi # Copy args pushed by PLT in register.
38 movq %rsi, %r11 # Multiply by 24
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.
52 addq $72, %rsp # Adjust stack(PLT did 2 pushes)
53 cfi_adjust_cfa_offset(-72)
54 jmp *%r11 # Jump to function address.
56 .size _dl_runtime_resolve, .-_dl_runtime_resolve
60 .globl _dl_runtime_profile
61 .type _dl_runtime_profile, @function
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
75 cfi_rel_offset(%rbx, 0)
79 48(%rbx) return address
84 24(%rbx) La_x86_64_regs pointer
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)
99 movq %rdx, (%rsp) # Fill the La_x86_64_regs structure.
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.
123 movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_offset
125 call _dl_profile_fixup # Call resolver.
127 movq %rax, %r11 # Save return value.
129 movq 8(%rbx), %rax # Get back register content.
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?
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.
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
174 andq $0xfffffffffffffff0, %r10
182 movq 24(%rdi), %rcx # Get back register content.
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.
200 movaps %xmm0, 16(%rcx)
201 movaps %xmm1, 32(%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.
211 movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_offset
212 call _dl_call_pltexit
214 movq (%rsp), %rax # Restore return registers.
216 movaps 16(%rsp), %xmm0
217 movaps 32(%rsp), %xmm1
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)
232 .size _dl_runtime_profile, .-_dl_runtime_profile