1 /* Thread-local storage handling in the ELF dynamic linker. ARM version.
2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
20 #include <arm-features.h>
25 @ emit debug information with cfi
26 @ use arm-specific pseudos for unwinding itself
28 .hidden _dl_tlsdesc_return
29 .global _dl_tlsdesc_return
30 .type _dl_tlsdesc_return,#function
39 .size _dl_tlsdesc_return, .-_dl_tlsdesc_return
41 .hidden _dl_tlsdesc_undefweak
42 .global _dl_tlsdesc_undefweak
43 .type _dl_tlsdesc_undefweak,#function
47 _dl_tlsdesc_undefweak:
53 .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
56 .hidden _dl_tlsdesc_dynamic
57 .global _dl_tlsdesc_dynamic
58 .type _dl_tlsdesc_dynamic,#function
62 The assembly code that follows is a rendition of the following
63 C code, hand-optimized a little bit.
66 _dl_tlsdesc_dynamic(struct tlsdesc *tdp)
68 struct tlsdesc_dynamic_arg *td = tdp->argument.pointer;
69 dtv_t *dtv = (dtv_t *)THREAD_DTV();
70 if (__builtin_expect (td->gen_count <= dtv[0].counter
71 && dtv[td->tlsinfo.ti_module].pointer.val
72 != TLS_DTV_UNALLOCATED,
74 return dtv[td->tlsinfo.ti_module].pointer.val +
75 td->tlsinfo.ti_offset - __builtin_thread_pointer();
77 return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer();
85 /* Our calling convention is to clobber r0, r1 and the processor
86 flags. All others that are modified must be saved */
87 eabi_save ({r2,r3,r4,lr})
89 cfi_adjust_cfa_offset (16)
93 cfi_rel_offset (lr,12)
96 mov r4, r0 /* r4 = tp */
98 ldr r2, [r1, #8] /* gen_count */
103 #ifndef ARM_NO_INDEX_REGISTER
104 ldr r2, [r0, r3, lsl #3]
106 add lr, r0, r3, lsl #3
119 #if ((defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)) \
120 || defined (ARM_ALWAYS_BX))
122 cfi_adjust_cfa_offset (-16)
133 .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic