| 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 |