glibc/sysdeps/arm/dl-trampoline.S

219 lines
4.8 KiB
ArmAsm
Raw Normal View History

/* PLT trampolines. ARM version.
Copyright (C) 2005, 2010 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <libc-symbols.h>
#if defined(__USE_BX__)
#define BX(x) bx x
#else
#define BX(x) mov pc, x
#endif
.text
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, #function
.cfi_sections .debug_frame
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.
stmdb sp!,{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.
ldmia sp!, {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 .debug_frame
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]
mov lr, pc
BX(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