1/* PLT trampolines. i386 version. 2 Copyright (C) 2004-2021 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