1 /* Thread-local storage handling in the ELF dynamic linker. i386 version.
2 Copyright (C) 2004-2024 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/>. */
21 #include <cpu-features-offsets.h>
22 #include <features-offsets.h>
25 #ifndef DL_STACK_ALIGNMENT
28 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
30 __tls_get_addr may be called with 4-byte stack alignment. Although
31 this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume
32 that stack will be always aligned at 16 bytes. */
33 # define DL_STACK_ALIGNMENT 4
36 /* True if _dl_tlsdesc_dynamic should align stack for STATE_SAVE or align
37 stack to MINIMUM_ALIGNMENT bytes before calling ___tls_get_addr. */
38 #define DL_RUNTIME_RESOLVE_REALIGN_STACK \
39 (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \
40 || MINIMUM_ALIGNMENT > DL_STACK_ALIGNMENT)
44 /* This function is used to compute the TP offset for symbols in
45 Static TLS, i.e., whose TP offset is the same for all
48 The incoming %eax points to the TLS descriptor, such that
49 0(%eax) points to _dl_tlsdesc_return itself, and 4(%eax) holds
50 the TP offset of the symbol corresponding to the object
51 denoted by the argument. */
53 .hidden _dl_tlsdesc_return
54 .global _dl_tlsdesc_return
55 .type _dl_tlsdesc_return,@function
62 .size _dl_tlsdesc_return, .-_dl_tlsdesc_return
64 /* This function is used for undefined weak TLS symbols, for
65 which the base address (i.e., disregarding any addend) should
68 %eax points to the TLS descriptor, such that 0(%eax) points to
69 _dl_tlsdesc_undefweak itself, and 4(%eax) holds the addend.
70 We return the addend minus the TP, such that, when the caller
71 adds TP, it gets the addend back. If that's zero, as usual,
72 that's most likely a NULL pointer. */
74 .hidden _dl_tlsdesc_undefweak
75 .global _dl_tlsdesc_undefweak
76 .type _dl_tlsdesc_undefweak,@function
79 _dl_tlsdesc_undefweak:
84 .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
88 # define MINIMUM_ALIGNMENT 4
89 # define STATE_SAVE_ALIGNMENT 4
90 # define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fnsave
91 # include "dl-tlsdesc-dynamic.h"
92 # undef _dl_tlsdesc_dynamic
93 # undef MINIMUM_ALIGNMENT
96 # define MINIMUM_ALIGNMENT 16
99 # define STATE_SAVE_ALIGNMENT 16
100 # define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave
101 # include "dl-tlsdesc-dynamic.h"
102 # undef _dl_tlsdesc_dynamic
106 # define STATE_SAVE_ALIGNMENT 64
107 # define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave
108 # include "dl-tlsdesc-dynamic.h"
109 # undef _dl_tlsdesc_dynamic
113 # define STATE_SAVE_ALIGNMENT 64
114 # define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec
115 # include "dl-tlsdesc-dynamic.h"
116 # undef _dl_tlsdesc_dynamic