1/* PLT trampolines. i386 version.
2 Copyright (C) 2004-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <sysdep.h>
20#include <link-defines.h>
21
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 _CET_ENDBR
30 pushl %eax # Preserve registers otherwise clobbered.
31 cfi_adjust_cfa_offset (4)
32 pushl %ecx
33 cfi_adjust_cfa_offset (4)
34 pushl %edx
35 cfi_adjust_cfa_offset (4)
36 movl 16(%esp), %edx # Copy args pushed by PLT in register. Note
37 movl 12(%esp), %eax # that `fixup' takes its parameters in regs.
38 call _dl_fixup # Call resolver.
39 popl %edx # Get register content back.
40 cfi_adjust_cfa_offset (-4)
41 movl (%esp), %ecx
42 movl %eax, (%esp) # Store the function address.
43 movl 4(%esp), %eax
44 ret $12 # Jump to function address.
45 cfi_endproc
46 .size _dl_runtime_resolve, .-_dl_runtime_resolve
47
48# The SHSTK compatible version.
49 .text
50 .globl _dl_runtime_resolve_shstk
51 .type _dl_runtime_resolve_shstk, @function
52 cfi_startproc
53 .align 16
54_dl_runtime_resolve_shstk:
55 cfi_adjust_cfa_offset (8)
56 _CET_ENDBR
57 pushl %eax # Preserve registers otherwise clobbered.
58 cfi_adjust_cfa_offset (4)
59 pushl %edx
60 cfi_adjust_cfa_offset (4)
61 movl 12(%esp), %edx # Copy args pushed by PLT in register. Note
62 movl 8(%esp), %eax # that `fixup' takes its parameters in regs.
63 call _dl_fixup # Call resolver.
64 movl (%esp), %edx # Get register content back.
65 movl %eax, %ecx # Store the function address.
66 movl 4(%esp), %eax # Get register content back.
67 addl $16, %esp # Adjust stack: PLT1 + PLT2 + %eax + %edx
68 cfi_adjust_cfa_offset (-16)
69 jmp *%ecx # Jump to function address.
70 cfi_endproc
71 .size _dl_runtime_resolve_shstk, .-_dl_runtime_resolve_shstk
72
73#ifndef PROF
74# The SHSTK compatible version.
75 .globl _dl_runtime_profile_shstk
76 .type _dl_runtime_profile_shstk, @function
77 cfi_startproc
78 .align 16
79_dl_runtime_profile_shstk:
80 cfi_adjust_cfa_offset (8)
81 _CET_ENDBR
82 pushl %esp
83 cfi_adjust_cfa_offset (4)
84 addl $8, (%esp) # Account for the pushed PLT data
85 pushl %ebp
86 cfi_adjust_cfa_offset (4)
87 pushl %eax # Preserve registers otherwise clobbered.
88 cfi_adjust_cfa_offset (4)
89 pushl %ecx
90 cfi_adjust_cfa_offset (4)
91 pushl %edx
92 cfi_adjust_cfa_offset (4)
93 movl %esp, %ecx
94 subl $8, %esp
95 cfi_adjust_cfa_offset (8)
96 movl $-1, 4(%esp)
97 leal 4(%esp), %edx
98 movl %edx, (%esp)
99 pushl %ecx # Address of the register structure
100 cfi_adjust_cfa_offset (4)
101 movl 40(%esp), %ecx # Load return address
102 movl 36(%esp), %edx # Copy args pushed by PLT in register. Note
103 movl 32(%esp), %eax # that `fixup' takes its parameters in regs.
104 call _dl_profile_fixup # Call resolver.
105 cfi_adjust_cfa_offset (-8)
106 movl (%esp), %edx
107 testl %edx, %edx
108 jns 1f
109 movl 4(%esp), %edx # Get register content back.
110 movl %eax, %ecx # Store the function address.
111 movl 12(%esp), %eax # Get register content back.
112 # Adjust stack: PLT1 + PLT2 + %esp + %ebp + %eax + %ecx + %edx
113 # + free.
114 addl $32, %esp
115 cfi_adjust_cfa_offset (-32)
116 jmp *%ecx # Jump to function address.
117 cfi_endproc
118 .size _dl_runtime_profile_shstk, .-_dl_runtime_profile_shstk
119
120 .globl _dl_runtime_profile
121 .type _dl_runtime_profile, @function
122 cfi_startproc
123 .align 16
124_dl_runtime_profile:
125 cfi_adjust_cfa_offset (8)
126 _CET_ENDBR
127 pushl %esp
128 cfi_adjust_cfa_offset (4)
129 addl $8, (%esp) # Account for the pushed PLT data
130 pushl %ebp
131 cfi_adjust_cfa_offset (4)
132 pushl %eax # Preserve registers otherwise clobbered.
133 cfi_adjust_cfa_offset (4)
134 pushl %ecx
135 cfi_adjust_cfa_offset (4)
136 pushl %edx
137 cfi_adjust_cfa_offset (4)
138 movl %esp, %ecx
139 subl $8, %esp
140 cfi_adjust_cfa_offset (8)
141 movl $-1, 4(%esp)
142 leal 4(%esp), %edx
143 movl %edx, (%esp)
144 pushl %ecx # Address of the register structure
145 cfi_adjust_cfa_offset (4)
146 movl 40(%esp), %ecx # Load return address
147 movl 36(%esp), %edx # Copy args pushed by PLT in register. Note
148 movl 32(%esp), %eax # that `fixup' takes its parameters in regs.
149 call _dl_profile_fixup # Call resolver.
150 cfi_adjust_cfa_offset (-8)
151 movl (%esp), %edx
152 testl %edx, %edx
153 jns 1f
154 popl %edx
155 cfi_adjust_cfa_offset (-4)
156 popl %edx # Get register content back.
157 cfi_adjust_cfa_offset (-4)
158 movl (%esp), %ecx
159 movl %eax, (%esp) # Store the function address.
160 movl 4(%esp), %eax
161 ret $20 # Jump to function address.
162
163 /*
164 +32 return address
165 +28 PLT1
166 +24 PLT2
167 +20 %esp
168 +16 %ebp
169 +12 %eax
170 +8 %ecx
171 +4 %edx
172 %esp free
173 */
174 cfi_adjust_cfa_offset (8)
1751: movl %ebx, (%esp)
176 cfi_rel_offset (ebx, 0)
177 movl %edx, %ebx # This is the frame buffer size
178 pushl %edi
179 cfi_adjust_cfa_offset (4)
180 cfi_rel_offset (edi, 0)
181 pushl %esi
182 cfi_adjust_cfa_offset (4)
183 cfi_rel_offset (esi, 0)
184 leal 44(%esp), %esi
185 movl %ebx, %ecx
186 orl $4, %ebx # Increase frame size if necessary to align
187 # stack for the function call
188 andl $~3, %ebx
189 movl %esp, %edi
190 subl %ebx, %edi
191 movl %esp, %ebx
192 cfi_def_cfa_register (ebx)
193 movl %edi, %esp
194 shrl $2, %ecx
195 rep
196 movsl
197 movl (%ebx), %esi
198 cfi_restore (esi)
199 movl 4(%ebx), %edi
200 cfi_restore (edi)
201 /*
202 %ebx+40 return address
203 %ebx+36 PLT1
204 %ebx+32 PLT2
205 %ebx+28 %esp
206 %ebx+24 %ebp
207 %ebx+20 %eax
208 %ebx+16 %ecx
209 %ebx+12 %edx
210 %ebx+8 %ebx
211 %ebx+4 free
212 %ebx free
213 %esp copied stack frame
214 */
215 movl %eax, (%ebx)
216 movl 12(%ebx), %edx
217 movl 16(%ebx), %ecx
218 movl 20(%ebx), %eax
219 call *(%ebx)
220 movl %ebx, %esp
221 cfi_def_cfa_register (esp)
222 movl 8(%esp), %ebx
223 cfi_restore (ebx)
224 /*
225 +40 return address
226 +36 PLT1
227 +32 PLT2
228 +28 %esp
229 +24 %ebp
230 +20 %eax
231 +16 %ecx
232 +12 %edx
233 +8 free
234 +4 free
235 %esp free
236 */
237#if LONG_DOUBLE_SIZE != 12
238# error "long double size must be 12 bytes"
239#endif
240 # Allocate space for La_i86_retval and subtract 12 free bytes.
241 subl $(LRV_SIZE - 12), %esp
242 cfi_adjust_cfa_offset (LRV_SIZE - 12)
243 movl %eax, LRV_EAX_OFFSET(%esp)
244 movl %edx, LRV_EDX_OFFSET(%esp)
245 fstpt LRV_ST0_OFFSET(%esp)
246 fstpt LRV_ST1_OFFSET(%esp)
247 pushl %esp
248 cfi_adjust_cfa_offset (4)
249 # Address of La_i86_regs area.
250 leal (LRV_SIZE + 4)(%esp), %ecx
251 # PLT2
252 movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax
253 # PLT1
254 movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx
255 call _dl_audit_pltexit
256 movl LRV_EAX_OFFSET(%esp), %eax
257 movl LRV_EDX_OFFSET(%esp), %edx
258 fldt LRV_ST1_OFFSET(%esp)
259 fldt LRV_ST0_OFFSET(%esp)
260 # Restore stack before return.
261 addl $(LRV_SIZE + 4 + LR_SIZE + 4), %esp
262 cfi_adjust_cfa_offset (-(LRV_SIZE + 4 + LR_SIZE + 4))
263 ret
264 cfi_endproc
265 .size _dl_runtime_profile, .-_dl_runtime_profile
266#endif
267

source code of glibc/sysdeps/i386/dl-trampoline.S