1/* Stack-aligning implementation of __tls_get_addr. x86-64 version. 2 Copyright (C) 2017-2022 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#ifdef SHARED 20 21# include <sysdep.h> 22# include "tlsdesc.h" 23# include "rtld-offsets.h" 24 25/* See __tls_get_addr and __tls_get_addr_slow in dl-tls.c. This function 26 call __tls_get_addr_slow on both slow paths. It realigns the stack 27 before the call to work around GCC PR58066. */ 28 29ENTRY (__tls_get_addr) 30 mov %fs:DTV_OFFSET, %RDX_LP 31 mov GL_TLS_GENERATION_OFFSET+_rtld_local(%rip), %RAX_LP 32 /* GL(dl_tls_generation) == dtv[0].counter */ 33 cmp %RAX_LP, (%rdx) 34 jne 1f 35 mov TI_MODULE_OFFSET(%rdi), %RAX_LP 36 /* dtv[ti->ti_module] */ 37# ifdef __LP64__ 38 salq $4, %rax 39 movq (%rdx,%rax), %rax 40# else 41 movl (%rdx,%rax, 8), %eax 42# endif 43 cmp $-1, %RAX_LP 44 je 1f 45 add TI_OFFSET_OFFSET(%rdi), %RAX_LP 46 ret 471: 48 /* On the slow path, align the stack. */ 49 pushq %rbp 50 cfi_def_cfa_offset (16) 51 cfi_offset (%rbp, -16) 52 mov %RSP_LP, %RBP_LP 53 cfi_def_cfa_register (%rbp) 54 and $-16, %RSP_LP 55 call __tls_get_addr_slow 56 mov %RBP_LP, %RSP_LP 57 popq %rbp 58 cfi_def_cfa (%rsp, 8) 59 ret 60END (__tls_get_addr) 61#endif /* SHARED */ 62