1/* PLT trampolines. i386 version.
2 Copyright (C) 2004-2024 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 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
46
47#if !defined PROF && defined SHARED
48 .globl _dl_runtime_profile
49 .type _dl_runtime_profile, @function
50 cfi_startproc
51 .align 16
52_dl_runtime_profile:
53 cfi_adjust_cfa_offset (8)
54 pushl %esp
55 cfi_adjust_cfa_offset (4)
56 addl $8, (%esp) # Account for the pushed PLT data
57 pushl %ebp
58 cfi_adjust_cfa_offset (4)
59 pushl %eax # Preserve registers otherwise clobbered.
60 cfi_adjust_cfa_offset (4)
61 pushl %ecx
62 cfi_adjust_cfa_offset (4)
63 pushl %edx
64 cfi_adjust_cfa_offset (4)
65 movl %esp, %ecx
66 subl $8, %esp
67 cfi_adjust_cfa_offset (8)
68 movl $-1, 4(%esp)
69 leal 4(%esp), %edx
70 movl %edx, (%esp)
71 pushl %ecx # Address of the register structure
72 cfi_adjust_cfa_offset (4)
73 movl 40(%esp), %ecx # Load return address
74 movl 36(%esp), %edx # Copy args pushed by PLT in register. Note
75 movl 32(%esp), %eax # that `fixup' takes its parameters in regs.
76 call _dl_profile_fixup # Call resolver.
77 cfi_adjust_cfa_offset (-8)
78 movl (%esp), %edx
79 testl %edx, %edx
80 jns 1f
81 popl %edx
82 cfi_adjust_cfa_offset (-4)
83 popl %edx # Get register content back.
84 cfi_adjust_cfa_offset (-4)
85 movl (%esp), %ecx
86 movl %eax, (%esp) # Store the function address.
87 movl 4(%esp), %eax
88 ret $20 # Jump to function address.
89
90 /*
91 +32 return address
92 +28 PLT1
93 +24 PLT2
94 +20 %esp
95 +16 %ebp
96 +12 %eax
97 +8 %ecx
98 +4 %edx
99 %esp free
100 */
101 cfi_adjust_cfa_offset (8)
1021: movl %ebx, (%esp)
103 cfi_rel_offset (ebx, 0)
104 movl %edx, %ebx # This is the frame buffer size
105 pushl %edi
106 cfi_adjust_cfa_offset (4)
107 cfi_rel_offset (edi, 0)
108 pushl %esi
109 cfi_adjust_cfa_offset (4)
110 cfi_rel_offset (esi, 0)
111 leal 44(%esp), %esi
112 movl %ebx, %ecx
113 orl $4, %ebx # Increase frame size if necessary to align
114 # stack for the function call
115 andl $~3, %ebx
116 movl %esp, %edi
117 subl %ebx, %edi
118 movl %esp, %ebx
119 cfi_def_cfa_register (ebx)
120 movl %edi, %esp
121 shrl $2, %ecx
122 rep
123 movsl
124 movl (%ebx), %esi
125 cfi_restore (esi)
126 movl 4(%ebx), %edi
127 cfi_restore (edi)
128 /*
129 %ebx+40 return address
130 %ebx+36 PLT1
131 %ebx+32 PLT2
132 %ebx+28 %esp
133 %ebx+24 %ebp
134 %ebx+20 %eax
135 %ebx+16 %ecx
136 %ebx+12 %edx
137 %ebx+8 %ebx
138 %ebx+4 free
139 %ebx free
140 %esp copied stack frame
141 */
142 movl %eax, (%ebx)
143 movl 12(%ebx), %edx
144 movl 16(%ebx), %ecx
145 movl 20(%ebx), %eax
146 call *(%ebx)
147 movl %ebx, %esp
148 cfi_def_cfa_register (esp)
149 movl 8(%esp), %ebx
150 cfi_restore (ebx)
151 /*
152 +40 return address
153 +36 PLT1
154 +32 PLT2
155 +28 %esp
156 +24 %ebp
157 +20 %eax
158 +16 %ecx
159 +12 %edx
160 +8 free
161 +4 free
162 %esp free
163 */
164#if LONG_DOUBLE_SIZE != 12
165# error "long double size must be 12 bytes"
166#endif
167 # Allocate space for La_i86_retval and subtract 12 free bytes.
168 subl $(LRV_SIZE - 12), %esp
169 cfi_adjust_cfa_offset (LRV_SIZE - 12)
170 movl %eax, LRV_EAX_OFFSET(%esp)
171 movl %edx, LRV_EDX_OFFSET(%esp)
172 fstpt LRV_ST0_OFFSET(%esp)
173 fstpt LRV_ST1_OFFSET(%esp)
174 pushl %esp
175 cfi_adjust_cfa_offset (4)
176 # Address of La_i86_regs area.
177 leal (LRV_SIZE + 4)(%esp), %ecx
178 # PLT2
179 movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax
180 # PLT1
181 movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx
182 call _dl_audit_pltexit
183 movl LRV_EAX_OFFSET(%esp), %eax
184 movl LRV_EDX_OFFSET(%esp), %edx
185 fldt LRV_ST1_OFFSET(%esp)
186 fldt LRV_ST0_OFFSET(%esp)
187 # Restore stack before return.
188 addl $(LRV_SIZE + 4 + LR_SIZE + 4), %esp
189 cfi_adjust_cfa_offset (-(LRV_SIZE + 4 + LR_SIZE + 4))
190 ret
191 cfi_endproc
192 .size _dl_runtime_profile, .-_dl_runtime_profile
193#endif
194

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