| 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 |