2.9
[glibc/nacl-glibc.git] / sysdeps / i386 / dl-trampoline.S
blob73b08ba67e4ee9f8141be022b0e047c380bc8b9e
1 /* PLT trampolines.  i386 version.
2    Copyright (C) 2004, 2005, 2007 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         cfi_startproc
26         .align 16
27 _dl_runtime_resolve:
28         cfi_adjust_cfa_offset (8)
29         pushl %eax              # Preserve registers otherwise clobbered.
30         cfi_adjust_cfa_offset (4)
31         pushl %ecx
32         cfi_adjust_cfa_offset (4)
33         pushl %edx
34         cfi_adjust_cfa_offset (4)
35         movl 16(%esp), %edx     # Copy args pushed by PLT in register.  Note
36         movl 12(%esp), %eax     # that `fixup' takes its parameters in regs.
37         call _dl_fixup          # Call resolver.
38         popl %edx               # Get register content back.
39         cfi_adjust_cfa_offset (-4)
40         movl (%esp), %ecx
41         movl %eax, (%esp)       # Store the function address.
42         movl 4(%esp), %eax
43         ret $12                 # Jump to function address.
44         cfi_endproc
45         .size _dl_runtime_resolve, .-_dl_runtime_resolve
48 #ifndef PROF
49         .globl _dl_runtime_profile
50         .type _dl_runtime_profile, @function
51         cfi_startproc
52         .align 16
53 _dl_runtime_profile:
54         cfi_adjust_cfa_offset (8)
55         pushl %esp
56         cfi_adjust_cfa_offset (4)
57         addl $8, (%esp)         # Account for the pushed PLT data
58         pushl %ebp
59         cfi_adjust_cfa_offset (4)
60         pushl %eax              # Preserve registers otherwise clobbered.
61         cfi_adjust_cfa_offset (4)
62         pushl %ecx
63         cfi_adjust_cfa_offset (4)
64         pushl %edx
65         cfi_adjust_cfa_offset (4)
66         movl %esp, %ecx
67         subl $8, %esp
68         cfi_adjust_cfa_offset (8)
69         movl $-1, 4(%esp)
70         leal 4(%esp), %edx
71         movl %edx, (%esp)
72         pushl %ecx              # Address of the register structure
73         cfi_adjust_cfa_offset (4)
74         movl 40(%esp), %ecx     # Load return address
75         movl 36(%esp), %edx     # Copy args pushed by PLT in register.  Note
76         movl 32(%esp), %eax     # that `fixup' takes its parameters in regs.
77         call _dl_profile_fixup  # Call resolver.
78         cfi_adjust_cfa_offset (-8)
79         movl (%esp), %edx
80         testl %edx, %edx
81         jns 1f
82         popl %edx
83         cfi_adjust_cfa_offset (-4)
84         popl %edx               # Get register content back.
85         cfi_adjust_cfa_offset (-4)
86         movl (%esp), %ecx
87         movl %eax, (%esp)       # Store the function address.
88         movl 4(%esp), %eax
89         ret $20                 # Jump to function address.
91         /*
92             +32     return address
93             +28     PLT1
94             +24     PLT2
95             +20     %esp
96             +16     %ebp
97             +12     %eax
98             +8      %ecx
99             +4      %edx
100            %esp     free
101         */
102         cfi_adjust_cfa_offset (12)
103 1:      movl %ebx, (%esp)
104         cfi_rel_offset (ebx, 0)
105         movl %edx, %ebx         # This is the frame buffer size
106         pushl %edi
107         cfi_adjust_cfa_offset (4)
108         cfi_rel_offset (edi, 0)
109         pushl %esi
110         cfi_adjust_cfa_offset (4)
111         cfi_rel_offset (esi, 0)
112         leal 44(%esp), %esi
113         movl %ebx, %ecx
114         orl $4, %ebx            # Increase frame size if necessary to align
115                                 # stack for the function call
116         andl $~3, %ebx
117         movl %esp, %edi
118         subl %ebx, %edi
119         movl %esp, %ebx
120         cfi_def_cfa_register (ebx)
121         movl %edi, %esp
122         shrl $2, %ecx
123         rep
124         movsl
125         movl (%ebx), %esi
126         cfi_restore (esi)
127         movl 4(%ebx), %edi
128         cfi_restore (edi)
129         /*
130            %ebx+40  return address
131            %ebx+36  PLT1
132            %ebx+32  PLT2
133            %ebx+28  %esp
134            %ebx+24  %ebp
135            %ebx+20  %eax
136            %ebx+16  %ecx
137            %ebx+12  %edx
138            %ebx+8   %ebx
139            %ebx+4   free
140            %ebx     free
141            %esp     copied stack frame
142         */
143         movl %eax, (%ebx)
144         movl 12(%ebx), %edx
145         movl 16(%ebx), %ecx
146         movl 20(%ebx), %eax
147         call *(%ebx)
148         movl %ebx, %esp
149         cfi_def_cfa_register (esp)
150         movl 8(%esp), %ebx
151         cfi_restore (ebx)
152         /*
153             +40     return address
154             +36     PLT1
155             +32     PLT2
156             +28     %esp
157             +24     %ebp
158             +20     %eax
159             +16     %ecx
160             +12     %edx
161             +8      free
162             +4      free
163            %esp     free
164         */
165         subl $20, %esp
166         cfi_adjust_cfa_offset (20)
167         movl %eax, (%esp)
168         movl %edx, 4(%esp)
169         fstpt 8(%esp)
170         fstpt 20(%esp)
171         pushl %esp
172         cfi_adjust_cfa_offset (4)
173         leal 36(%esp), %ecx
174         movl 56(%esp), %eax
175         movl 60(%esp), %edx
176         call _dl_call_pltexit
177         movl (%esp), %eax
178         movl 4(%esp), %edx
179         fldt 20(%esp)
180         fldt 8(%esp)
181         addl $60, %esp
182         cfi_adjust_cfa_offset (-60)
183         ret
184         cfi_endproc
185         .size _dl_runtime_profile, .-_dl_runtime_profile
186 #endif