1/* PLT trampolines. ARM version. 2 Copyright (C) 2005-2022 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 <https://www.gnu.org/licenses/>. */ 18 19/* ??? Needs more rearrangement for the LDM to handle thumb mode. */ 20#define NO_THUMB 21#include <sysdep.h> 22#include <libc-symbols.h> 23 24 .text 25 .globl _dl_runtime_resolve 26 .type _dl_runtime_resolve, #function 27 CFI_SECTIONS 28 cfi_startproc 29 .align 2 30_dl_runtime_resolve: 31 cfi_adjust_cfa_offset (4) 32 cfi_rel_offset (lr, 0) 33 34 @ we get called with 35 @ stack[0] contains the return address from this call 36 @ ip contains &GOT[n+3] (pointer to function) 37 @ lr points to &GOT[2] 38 39 @ Save arguments. We save r4 to realign the stack. 40 push {r0-r4} 41 cfi_adjust_cfa_offset (20) 42 cfi_rel_offset (r0, 0) 43 cfi_rel_offset (r1, 4) 44 cfi_rel_offset (r2, 8) 45 cfi_rel_offset (r3, 12) 46 47 @ get pointer to linker struct 48 ldr r0, [lr, #-4] 49 50 @ prepare to call _dl_fixup() 51 @ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each 52 sub r1, ip, lr 53 sub r1, r1, #4 54 add r1, r1, r1 55 56 @ call fixup routine 57 bl _dl_fixup 58 59 @ save the return 60 mov ip, r0 61 62 @ get arguments and return address back. We restore r4 63 @ only to realign the stack. 64 pop {r0-r4,lr} 65 cfi_adjust_cfa_offset (-24) 66 67 @ jump to the newly found address 68 BX(ip) 69 70 cfi_endproc 71 .size _dl_runtime_resolve, .-_dl_runtime_resolve 72 73#ifndef PROF 74 .globl _dl_runtime_profile 75 .type _dl_runtime_profile, #function 76 CFI_SECTIONS 77 cfi_startproc 78 .align 2 79_dl_runtime_profile: 80 cfi_adjust_cfa_offset (4) 81 cfi_rel_offset (lr, 0) 82 83 @ we get called with 84 @ stack[0] contains the return address from this call 85 @ ip contains &GOT[n+3] (pointer to function) 86 @ lr points to &GOT[2] 87 88 @ Stack layout: 89 @ 212 - saved lr 90 @ 208 - framesize returned from pltenter 91 @ 16 - La_arm_regs 92 @ 8 - Saved two arguments to _dl_profile_fixup 93 @ 4 - Saved result of _dl_profile_fixup 94 @ 0 - outgoing argument to _dl_profile_fixup 95 @ For now, we only save the general purpose registers. 96 97 sub sp, sp, #196 98 cfi_adjust_cfa_offset (196) 99 stmia sp, {r0-r3} 100 cfi_rel_offset (r0, 0) 101 cfi_rel_offset (r1, 4) 102 cfi_rel_offset (r2, 8) 103 cfi_rel_offset (r3, 12) 104 105 sub sp, sp, #16 106 cfi_adjust_cfa_offset (16) 107 108 @ Save sp and lr. 109 add r0, sp, #216 110 str r0, [sp, #32] 111 ldr r2, [sp, #212] 112 str r2, [sp, #36] 113 114 @ get pointer to linker struct 115 ldr r0, [lr, #-4] 116 117 @ prepare to call _dl_profile_fixup() 118 @ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each 119 sub r1, ip, lr 120 sub r1, r1, #4 121 add r1, r1, r1 122 123 @ Save these two arguments for pltexit. 124 add r3, sp, #8 125 stmia r3!, {r0,r1} 126 127 @ Set up extra args for _dl_profile_fixup. 128 @ r2 and r3 are already loaded. 129 add ip, sp, #208 130 str ip, [sp, #0] 131 132 @ call profiling fixup routine 133 bl _dl_profile_fixup 134 135 @ The address to call is now in r0. 136 137 @ Check whether we're wrapping this function. 138 ldr ip, [sp, #208] 139 cmp ip, #0 140 bge 1f 141 cfi_remember_state 142 143 @ save the return 144 mov ip, r0 145 146 @ get arguments and return address back 147 add sp, sp, #16 148 cfi_adjust_cfa_offset (-16) 149 ldmia sp, {r0-r3,sp,lr} 150 cfi_adjust_cfa_offset (-200) 151 152 @ jump to the newly found address 153 BX(ip) 154 155 cfi_restore_state 1561: 157 @ The new frame size is in ip. 158 159 @ New stack layout: 160 @ 268 - saved r7 161 @ 264 - saved result of _dl_profile_fixup 162 @ 72 - La_arm_regs 163 @ 64 - Saved two arguments to _dl_profile_fixup 164 @ 0 - La_arm_retval 165 @ For now, we only save the general purpose registers. 166 167 @ Build the new frame. 168 str r7, [sp, #212] 169 cfi_rel_offset (r7, 212) 170 sub r7, sp, #56 171 cfi_def_cfa_register (r7) 172 cfi_adjust_cfa_offset (56) 173 sub sp, sp, ip 174 bic sp, sp, #7 175 176 @ Save the _dl_profile_fixup result around the call to memcpy. 177 str r0, [r7, #264] 178 179 @ Copy the stack arguments. 180 mov r0, sp 181 add r1, r7, #272 182 mov r2, ip 183 bl memcpy 184 185 @ Call the function. 186 add ip, r7, #72 187 ldmia ip, {r0-r3} 188 ldr ip, [r7, #264] 189 BLX(ip) 190 stmia r7, {r0-r3} 191 192 @ Call pltexit. 193 add ip, r7, #64 194 ldmia ip, {r0,r1} 195 add r2, r7, #72 196 add r3, r7, #0 197 bl _dl_audit_pltexit 198 199 @ Return to caller. 200 ldmia r7, {r0-r3} 201 mov sp, r7 202 cfi_def_cfa_register (sp) 203 ldr r7, [sp, #268] 204 ldr lr, [sp, #92] 205 add sp, sp, #272 206 cfi_adjust_cfa_offset (-272) 207 BX(lr) 208 209 cfi_endproc 210 .size _dl_runtime_profile, .-_dl_runtime_profile 211#endif 212 .previous 213