xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame^] | 1 | /* Implementation of profiling support. ARM EABI version. |
| 2 | Copyright (C) 2008-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 | /* Don't call mcount when calling mcount... */ |
| 20 | #undef PROF |
| 21 | |
| 22 | #include <sysdep.h> |
| 23 | |
| 24 | #undef mcount |
| 25 | |
| 26 | #ifdef __thumb2__ |
| 27 | .thumb |
| 28 | #endif |
| 29 | .syntax unified |
| 30 | |
| 31 | |
| 32 | /* Use an assembly stub with a special ABI. The calling lr has been |
| 33 | pushed to the stack (which will be misaligned). We should preserve |
| 34 | all registers except ip and pop a word off the stack. |
| 35 | |
| 36 | NOTE: This assumes mcount_internal does not clobber any non-core |
| 37 | (coprocessor) registers. Currently this is true, but may require |
| 38 | additional attention in the future. |
| 39 | |
| 40 | The calling sequence looks something like: |
| 41 | func: |
| 42 | push {lr} |
| 43 | bl __gnu_mcount_nc |
| 44 | <function body> |
| 45 | */ |
| 46 | |
| 47 | ENTRY(__gnu_mcount_nc) |
| 48 | push {r0, r1, r2, r3, lr} |
| 49 | cfi_adjust_cfa_offset (20) |
| 50 | cfi_rel_offset (r0, 0) |
| 51 | cfi_rel_offset (r1, 4) |
| 52 | cfi_rel_offset (r2, 8) |
| 53 | cfi_rel_offset (r3, 12) |
| 54 | cfi_rel_offset (lr, 16) |
| 55 | bic r1, lr, #1 |
| 56 | ldr r0, [sp, #20] |
| 57 | bl __mcount_internal |
| 58 | pop {r0, r1, r2, r3, ip, lr} |
| 59 | cfi_adjust_cfa_offset (-24) |
| 60 | cfi_restore (r0) |
| 61 | cfi_restore (r1) |
| 62 | cfi_restore (r2) |
| 63 | cfi_restore (r3) |
| 64 | cfi_register (lr, ip) |
| 65 | bx ip |
| 66 | END(__gnu_mcount_nc) |
| 67 | |
| 68 | |
| 69 | #include <gcc-compat.h> |
| 70 | #include <shlib-compat.h> |
| 71 | |
| 72 | /* The new __gnu_mcount_nc entry point was introduced in 4.4, so the |
| 73 | static library needs the old one only to support older compilers. |
| 74 | Even in a configuration that only cares about newer compilers, the |
| 75 | shared library might need it only for strict ABI compatibility. */ |
| 76 | |
| 77 | #if GCC_COMPAT (4, 3) || SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) |
| 78 | |
| 79 | /* Provide old mcount for backwards compatibility. This requires |
| 80 | code be compiled with APCS frame pointers. */ |
| 81 | |
| 82 | ENTRY(__mcount_arm_compat) |
| 83 | push {r0, r1, r2, r3, fp, lr} |
| 84 | cfi_adjust_cfa_offset (24) |
| 85 | cfi_rel_offset (r0, 0) |
| 86 | cfi_rel_offset (r1, 4) |
| 87 | cfi_rel_offset (r2, 8) |
| 88 | cfi_rel_offset (r3, 12) |
| 89 | cfi_rel_offset (fp, 16) |
| 90 | cfi_rel_offset (lr, 20) |
| 91 | movs r0, fp |
| 92 | ittt ne |
| 93 | sfi_breg r0, \ |
| 94 | ldrne r0, [\B, #-4] |
| 95 | movsne r1, lr |
| 96 | blne __mcount_internal |
| 97 | # if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__) |
| 98 | pop {r0, r1, r2, r3, fp, lr} |
| 99 | cfi_adjust_cfa_offset (-24) |
| 100 | cfi_restore (r0) |
| 101 | cfi_restore (r1) |
| 102 | cfi_restore (r2) |
| 103 | cfi_restore (r3) |
| 104 | cfi_restore (fp) |
| 105 | cfi_restore (lr) |
| 106 | bx lr |
| 107 | # else |
| 108 | pop {r0, r1, r2, r3, fp, pc} |
| 109 | # endif |
| 110 | END(__mcount_arm_compat) |
| 111 | |
| 112 | #endif |
| 113 | |
| 114 | #if GCC_COMPAT (4, 3) |
| 115 | |
| 116 | strong_alias (__mcount_arm_compat, _mcount) |
| 117 | |
| 118 | /* The canonical name for the function is `_mcount' in both C and asm, |
| 119 | but some old asm code might assume it's `mcount'. */ |
| 120 | weak_alias (_mcount, mcount) |
| 121 | |
| 122 | #elif SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) |
| 123 | |
| 124 | compat_symbol (libc, __mcount_arm_compat, _mcount, GLIBC_2_0) |
| 125 | |
| 126 | strong_alias (__mcount_arm_compat, __mcount_arm_compat_1) |
| 127 | compat_symbol (libc, __mcount_arm_compat_1, mcount, GLIBC_2_0) |
| 128 | |
| 129 | #endif |