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