Add test case for bug 18287
[glibc.git] / sysdeps / i386 / dl-trampoline.S
blob8a2fd8ddd63de768c7008dda149050bc91ad2066
1 /* PLT trampolines.  i386 version.
2    Copyright (C) 2004-2015 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, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <link-defines.h>
22 #ifdef HAVE_MPX_SUPPORT
23 # define PRESERVE_BND_REGS_PREFIX bnd
24 #else
25 # define PRESERVE_BND_REGS_PREFIX .byte 0xf2
26 #endif
28         .text
29         .globl _dl_runtime_resolve
30         .type _dl_runtime_resolve, @function
31         cfi_startproc
32         .align 16
33 _dl_runtime_resolve:
34         cfi_adjust_cfa_offset (8)
35         pushl %eax              # Preserve registers otherwise clobbered.
36         cfi_adjust_cfa_offset (4)
37         pushl %ecx
38         cfi_adjust_cfa_offset (4)
39         pushl %edx
40         cfi_adjust_cfa_offset (4)
41         movl 16(%esp), %edx     # Copy args pushed by PLT in register.  Note
42         movl 12(%esp), %eax     # that `fixup' takes its parameters in regs.
43         call _dl_fixup          # Call resolver.
44         popl %edx               # Get register content back.
45         cfi_adjust_cfa_offset (-4)
46         movl (%esp), %ecx
47         movl %eax, (%esp)       # Store the function address.
48         movl 4(%esp), %eax
49         ret $12                 # Jump to function address.
50         cfi_endproc
51         .size _dl_runtime_resolve, .-_dl_runtime_resolve
54 #ifndef PROF
55         .globl _dl_runtime_profile
56         .type _dl_runtime_profile, @function
57         cfi_startproc
58         .align 16
59 _dl_runtime_profile:
60         cfi_adjust_cfa_offset (8)
61         pushl %esp
62         cfi_adjust_cfa_offset (4)
63         addl $8, (%esp)         # Account for the pushed PLT data
64         pushl %ebp
65         cfi_adjust_cfa_offset (4)
66         pushl %eax              # Preserve registers otherwise clobbered.
67         cfi_adjust_cfa_offset (4)
68         pushl %ecx
69         cfi_adjust_cfa_offset (4)
70         pushl %edx
71         cfi_adjust_cfa_offset (4)
72         movl %esp, %ecx
73         subl $8, %esp
74         cfi_adjust_cfa_offset (8)
75         movl $-1, 4(%esp)
76         leal 4(%esp), %edx
77         movl %edx, (%esp)
78         pushl %ecx              # Address of the register structure
79         cfi_adjust_cfa_offset (4)
80         movl 40(%esp), %ecx     # Load return address
81         movl 36(%esp), %edx     # Copy args pushed by PLT in register.  Note
82         movl 32(%esp), %eax     # that `fixup' takes its parameters in regs.
83         call _dl_profile_fixup  # Call resolver.
84         cfi_adjust_cfa_offset (-8)
85         movl (%esp), %edx
86         testl %edx, %edx
87         jns 1f
88         popl %edx
89         cfi_adjust_cfa_offset (-4)
90         popl %edx               # Get register content back.
91         cfi_adjust_cfa_offset (-4)
92         movl (%esp), %ecx
93         movl %eax, (%esp)       # Store the function address.
94         movl 4(%esp), %eax
95         ret $20                 # Jump to function address.
97         /*
98             +32     return address
99             +28     PLT1
100             +24     PLT2
101             +20     %esp
102             +16     %ebp
103             +12     %eax
104             +8      %ecx
105             +4      %edx
106            %esp     free
107         */
108         cfi_adjust_cfa_offset (8)
109 1:      movl %ebx, (%esp)
110         cfi_rel_offset (ebx, 0)
111         movl %edx, %ebx         # This is the frame buffer size
112         pushl %edi
113         cfi_adjust_cfa_offset (4)
114         cfi_rel_offset (edi, 0)
115         pushl %esi
116         cfi_adjust_cfa_offset (4)
117         cfi_rel_offset (esi, 0)
118         leal 44(%esp), %esi
119         movl %ebx, %ecx
120         orl $4, %ebx            # Increase frame size if necessary to align
121                                 # stack for the function call
122         andl $~3, %ebx
123         movl %esp, %edi
124         subl %ebx, %edi
125         movl %esp, %ebx
126         cfi_def_cfa_register (ebx)
127         movl %edi, %esp
128         shrl $2, %ecx
129         rep
130         movsl
131         movl (%ebx), %esi
132         cfi_restore (esi)
133         movl 4(%ebx), %edi
134         cfi_restore (edi)
135         /*
136            %ebx+40  return address
137            %ebx+36  PLT1
138            %ebx+32  PLT2
139            %ebx+28  %esp
140            %ebx+24  %ebp
141            %ebx+20  %eax
142            %ebx+16  %ecx
143            %ebx+12  %edx
144            %ebx+8   %ebx
145            %ebx+4   free
146            %ebx     free
147            %esp     copied stack frame
148         */
149         movl %eax, (%ebx)
150         movl 12(%ebx), %edx
151         movl 16(%ebx), %ecx
152         movl 20(%ebx), %eax
153         call *(%ebx)
154         movl %ebx, %esp
155         cfi_def_cfa_register (esp)
156         movl 8(%esp), %ebx
157         cfi_restore (ebx)
158         /*
159             +40     return address
160             +36     PLT1
161             +32     PLT2
162             +28     %esp
163             +24     %ebp
164             +20     %eax
165             +16     %ecx
166             +12     %edx
167             +8      free
168             +4      free
169            %esp     free
170         */
171 #if LONG_DOUBLE_SIZE != 12
172 # error "long double size must be 12 bytes"
173 #endif
174         # Allocate space for La_i86_retval and subtract 12 free bytes.
175         subl $(LRV_SIZE - 12), %esp
176         cfi_adjust_cfa_offset (LRV_SIZE - 12)
177         movl %eax, LRV_EAX_OFFSET(%esp)
178         movl %edx, LRV_EDX_OFFSET(%esp)
179         fstpt LRV_ST0_OFFSET(%esp)
180         fstpt LRV_ST1_OFFSET(%esp)
181 #ifdef HAVE_MPX_SUPPORT
182         bndmov %bnd0, LRV_BND0_OFFSET(%esp)
183         bndmov %bnd1, LRV_BND1_OFFSET(%esp)
184 #else
185         .byte 0x66,0x0f,0x1b,0x44,0x24,LRV_BND0_OFFSET
186         .byte 0x66,0x0f,0x1b,0x4c,0x24,LRV_BND1_OFFSET
187 #endif
188         pushl %esp
189         cfi_adjust_cfa_offset (4)
190         # Address of La_i86_regs area.
191         leal (LRV_SIZE + 4)(%esp), %ecx
192         # PLT2
193         movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax
194         # PLT1
195         movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx
196         call _dl_call_pltexit
197         movl LRV_EAX_OFFSET(%esp), %eax
198         movl LRV_EDX_OFFSET(%esp), %edx
199         fldt LRV_ST1_OFFSET(%esp)
200         fldt LRV_ST0_OFFSET(%esp)
201 #ifdef HAVE_MPX_SUPPORT
202         bndmov LRV_BND0_OFFSET(%esp), %bnd0
203         bndmov LRV_BND1_OFFSET(%esp), %bnd1
204 #else
205         .byte 0x66,0x0f,0x1a,0x44,0x24,LRV_BND0_OFFSET
206         .byte 0x66,0x0f,0x1a,0x4c,0x24,LRV_BND1_OFFSET
207 #endif
208         # Restore stack before return.
209         addl $(LRV_SIZE + 4 + LR_SIZE + 4), %esp
210         cfi_adjust_cfa_offset (-(LRV_SIZE + 4 + LR_SIZE + 4))
211         PRESERVE_BND_REGS_PREFIX
212         ret
213         cfi_endproc
214         .size _dl_runtime_profile, .-_dl_runtime_profile
215 #endif