| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* PLT trampolines.  i386 version. | 
|  | 2 | Copyright (C) 2004-2016 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 | <http://www.gnu.org/licenses/>.  */ | 
|  | 18 |  | 
|  | 19 | #include <sysdep.h> | 
|  | 20 | #include <link-defines.h> | 
|  | 21 |  | 
|  | 22 | #ifdef HAVE_MPX_SUPPORT | 
|  | 23 | # define PRESERVE_BND_REGS_PREFIX bnd | 
|  | 24 | #else | 
|  | 25 | # define PRESERVE_BND_REGS_PREFIX .byte 0xf2 | 
|  | 26 | #endif | 
|  | 27 |  | 
|  | 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 | 
|  | 52 |  | 
|  | 53 |  | 
|  | 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. | 
|  | 96 |  | 
|  | 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 |