|  | /* PLT trampolines.  ARM version. | 
|  | Copyright (C) 2005-2016 Free Software Foundation, Inc. | 
|  | This file is part of the GNU C Library. | 
|  |  | 
|  | The GNU C Library is free software; you can redistribute it and/or | 
|  | modify it under the terms of the GNU Lesser General Public | 
|  | License as published by the Free Software Foundation; either | 
|  | version 2.1 of the License, or (at your option) any later version. | 
|  |  | 
|  | The GNU C Library is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | Lesser General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU Lesser General Public | 
|  | License along with the GNU C Library.  If not, see | 
|  | <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | /* ??? Needs more rearrangement for the LDM to handle thumb mode.  */ | 
|  | #define NO_THUMB | 
|  | #include <sysdep.h> | 
|  | #include <libc-symbols.h> | 
|  |  | 
|  | .text | 
|  | .globl _dl_runtime_resolve | 
|  | .type _dl_runtime_resolve, #function | 
|  | CFI_SECTIONS | 
|  | cfi_startproc | 
|  | .align 2 | 
|  | _dl_runtime_resolve: | 
|  | cfi_adjust_cfa_offset (4) | 
|  | cfi_rel_offset (lr, 0) | 
|  |  | 
|  | @ we get called with | 
|  | @ 	stack[0] contains the return address from this call | 
|  | @	ip contains &GOT[n+3] (pointer to function) | 
|  | @	lr points to &GOT[2] | 
|  |  | 
|  | @ Save arguments.  We save r4 to realign the stack. | 
|  | push	{r0-r4} | 
|  | cfi_adjust_cfa_offset (20) | 
|  | cfi_rel_offset (r0, 0) | 
|  | cfi_rel_offset (r1, 4) | 
|  | cfi_rel_offset (r2, 8) | 
|  | cfi_rel_offset (r3, 12) | 
|  |  | 
|  | @ get pointer to linker struct | 
|  | ldr	r0, [lr, #-4] | 
|  |  | 
|  | @ prepare to call _dl_fixup() | 
|  | @ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each | 
|  | sub	r1, ip, lr | 
|  | sub	r1, r1, #4 | 
|  | add	r1, r1, r1 | 
|  |  | 
|  | @ call fixup routine | 
|  | bl	_dl_fixup | 
|  |  | 
|  | @ save the return | 
|  | mov	ip, r0 | 
|  |  | 
|  | @ get arguments and return address back.  We restore r4 | 
|  | @ only to realign the stack. | 
|  | pop	{r0-r4,lr} | 
|  | cfi_adjust_cfa_offset (-24) | 
|  |  | 
|  | @ jump to the newly found address | 
|  | BX(ip) | 
|  |  | 
|  | cfi_endproc | 
|  | .size _dl_runtime_resolve, .-_dl_runtime_resolve | 
|  |  | 
|  | #ifndef PROF | 
|  | .globl _dl_runtime_profile | 
|  | .type _dl_runtime_profile, #function | 
|  | CFI_SECTIONS | 
|  | cfi_startproc | 
|  | .align 2 | 
|  | _dl_runtime_profile: | 
|  | cfi_adjust_cfa_offset (4) | 
|  | cfi_rel_offset (lr, 0) | 
|  |  | 
|  | @ we get called with | 
|  | @ 	stack[0] contains the return address from this call | 
|  | @	ip contains &GOT[n+3] (pointer to function) | 
|  | @	lr points to &GOT[2] | 
|  |  | 
|  | @ Stack layout: | 
|  | @ 212 - saved lr | 
|  | @ 208 - framesize returned from pltenter | 
|  | @ 16 - La_arm_regs | 
|  | @ 8 - Saved two arguments to _dl_profile_fixup | 
|  | @ 4 - Saved result of _dl_profile_fixup | 
|  | @ 0 - outgoing argument to _dl_profile_fixup | 
|  | @ For now, we only save the general purpose registers. | 
|  |  | 
|  | sub	sp, sp, #196 | 
|  | cfi_adjust_cfa_offset (196) | 
|  | stmia	sp, {r0-r3} | 
|  | cfi_rel_offset (r0, 0) | 
|  | cfi_rel_offset (r1, 4) | 
|  | cfi_rel_offset (r2, 8) | 
|  | cfi_rel_offset (r3, 12) | 
|  |  | 
|  | sub	sp, sp, #16 | 
|  | cfi_adjust_cfa_offset (16) | 
|  |  | 
|  | @ Save sp and lr. | 
|  | add	r0, sp, #216 | 
|  | str	r0, [sp, #32] | 
|  | ldr	r2, [sp, #212] | 
|  | str	r2, [sp, #36] | 
|  |  | 
|  | @ get pointer to linker struct | 
|  | ldr	r0, [lr, #-4] | 
|  |  | 
|  | @ prepare to call _dl_profile_fixup() | 
|  | @ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each | 
|  | sub	r1, ip, lr | 
|  | sub	r1, r1, #4 | 
|  | add	r1, r1, r1 | 
|  |  | 
|  | @ Save these two arguments for pltexit. | 
|  | add	r3, sp, #8 | 
|  | stmia	r3!, {r0,r1} | 
|  |  | 
|  | @ Set up extra args for _dl_profile_fixup. | 
|  | @ r2 and r3 are already loaded. | 
|  | add	ip, sp, #208 | 
|  | str	ip, [sp, #0] | 
|  |  | 
|  | @ call profiling fixup routine | 
|  | bl	_dl_profile_fixup | 
|  |  | 
|  | @ The address to call is now in r0. | 
|  |  | 
|  | @ Check whether we're wrapping this function. | 
|  | ldr	ip, [sp, #208] | 
|  | cmp	ip, #0 | 
|  | bge	1f | 
|  | cfi_remember_state | 
|  |  | 
|  | @ save the return | 
|  | mov	ip, r0 | 
|  |  | 
|  | @ get arguments and return address back | 
|  | add	sp, sp, #16 | 
|  | cfi_adjust_cfa_offset (-16) | 
|  | ldmia	sp, {r0-r3,sp,lr} | 
|  | cfi_adjust_cfa_offset (-200) | 
|  |  | 
|  | @ jump to the newly found address | 
|  | BX(ip) | 
|  |  | 
|  | cfi_restore_state | 
|  | 1: | 
|  | @ The new frame size is in ip. | 
|  |  | 
|  | @ New stack layout: | 
|  | @ 268 - saved r7 | 
|  | @ 264 - saved result of _dl_profile_fixup | 
|  | @ 72 - La_arm_regs | 
|  | @ 64 - Saved two arguments to _dl_profile_fixup | 
|  | @ 0 - La_arm_retval | 
|  | @ For now, we only save the general purpose registers. | 
|  |  | 
|  | @ Build the new frame. | 
|  | str	r7, [sp, #212] | 
|  | cfi_rel_offset (r7, 212) | 
|  | sub	r7, sp, #56 | 
|  | cfi_def_cfa_register (r7) | 
|  | cfi_adjust_cfa_offset (56) | 
|  | sub	sp, sp, ip | 
|  | bic	sp, sp, #7 | 
|  |  | 
|  | @ Save the _dl_profile_fixup result around the call to memcpy. | 
|  | str	r0, [r7, #264] | 
|  |  | 
|  | @ Copy the stack arguments. | 
|  | mov	r0, sp | 
|  | add	r1, r7, #272 | 
|  | mov	r2, ip | 
|  | bl	memcpy | 
|  |  | 
|  | @ Call the function. | 
|  | add	ip, r7, #72 | 
|  | ldmia	ip, {r0-r3} | 
|  | ldr	ip, [r7, #264] | 
|  | BLX(ip) | 
|  | stmia	r7, {r0-r3} | 
|  |  | 
|  | @ Call pltexit. | 
|  | add	ip, r7, #64 | 
|  | ldmia	ip, {r0,r1} | 
|  | add	r2, r7, #72 | 
|  | add	r3, r7, #0 | 
|  | bl	_dl_call_pltexit | 
|  |  | 
|  | @ Return to caller. | 
|  | ldmia	r7, {r0-r3} | 
|  | mov	sp, r7 | 
|  | cfi_def_cfa_register (sp) | 
|  | ldr	r7, [sp, #268] | 
|  | ldr	lr, [sp, #92] | 
|  | add	sp, sp, #272 | 
|  | cfi_adjust_cfa_offset (-272) | 
|  | BX(lr) | 
|  |  | 
|  | cfi_endproc | 
|  | .size _dl_runtime_profile, .-_dl_runtime_profile | 
|  | #endif | 
|  | .previous |