1/* Thread-local storage handling in the ELF dynamic linker. x86_64 version.
2 Copyright (C) 2004-2024 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#include <sysdep.h>
20#include <tls.h>
21#include <cpu-features-offsets.h>
22#include <features-offsets.h>
23#include <isa-level.h>
24#include "tlsdesc.h"
25#include "dl-trampoline-save.h"
26
27/* Area on stack to save and restore registers used for parameter
28 passing when calling _dl_tlsdesc_dynamic. */
29#define REGISTER_SAVE_RCX 0
30#define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8)
31#define REGISTER_SAVE_R8 (REGISTER_SAVE_RDX + 8)
32#define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8)
33#define REGISTER_SAVE_R10 (REGISTER_SAVE_R9 + 8)
34#define REGISTER_SAVE_R11 (REGISTER_SAVE_R10 + 8)
35
36 .text
37
38 /* This function is used to compute the TP offset for symbols in
39 Static TLS, i.e., whose TP offset is the same for all
40 threads.
41
42 The incoming %rax points to the TLS descriptor, such that
43 0(%rax) points to _dl_tlsdesc_return itself, and 8(%rax) holds
44 the TP offset of the symbol corresponding to the object
45 denoted by the argument. */
46
47 .hidden _dl_tlsdesc_return
48 .global _dl_tlsdesc_return
49 .type _dl_tlsdesc_return,@function
50 cfi_startproc
51 .align 16
52_dl_tlsdesc_return:
53 _CET_ENDBR
54 movq 8(%rax), %rax
55 ret
56 cfi_endproc
57 .size _dl_tlsdesc_return, .-_dl_tlsdesc_return
58
59 /* This function is used for undefined weak TLS symbols, for
60 which the base address (i.e., disregarding any addend) should
61 resolve to NULL.
62
63 %rax points to the TLS descriptor, such that 0(%rax) points to
64 _dl_tlsdesc_undefweak itself, and 8(%rax) holds the addend.
65 We return the addend minus the TP, such that, when the caller
66 adds TP, it gets the addend back. If that's zero, as usual,
67 that's most likely a NULL pointer. */
68
69 .hidden _dl_tlsdesc_undefweak
70 .global _dl_tlsdesc_undefweak
71 .type _dl_tlsdesc_undefweak,@function
72 cfi_startproc
73 .align 16
74_dl_tlsdesc_undefweak:
75 _CET_ENDBR
76 movq 8(%rax), %rax
77 sub %fs:0, %RAX_LP
78 ret
79 cfi_endproc
80 .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
81
82#ifdef SHARED
83# if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
84# define USE_FXSAVE
85# define STATE_SAVE_ALIGNMENT 16
86# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave
87# include "dl-tlsdesc-dynamic.h"
88# undef _dl_tlsdesc_dynamic
89# undef USE_FXSAVE
90# endif
91
92# define USE_XSAVE
93# define STATE_SAVE_ALIGNMENT 64
94# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave
95# include "dl-tlsdesc-dynamic.h"
96# undef _dl_tlsdesc_dynamic
97# undef USE_XSAVE
98
99# define USE_XSAVEC
100# define STATE_SAVE_ALIGNMENT 64
101# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec
102# include "dl-tlsdesc-dynamic.h"
103# undef _dl_tlsdesc_dynamic
104# undef USE_XSAVEC
105#endif /* SHARED */
106

source code of glibc/sysdeps/x86_64/dl-tlsdesc.S