1 /* Definitions for thread-local data handling. linuxthreads/x86-64 version. 2 Copyright (C) 2002, 2005 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 #ifndef _TLS_H 20 #define _TLS_H 21 22 #ifndef __ASSEMBLER__ 23 24 # include <pt-machine.h> 25 # include <stdbool.h> 26 # include <stddef.h> 27 28 /* Type for the dtv. */ 29 typedef union dtv 30 { 31 size_t counter; 32 struct 33 { 34 void *val; 35 bool is_static; 36 } pointer; 37 } dtv_t; 38 39 40 typedef struct 41 { 42 void *tcb; /* Pointer to the TCB. Not necessary the 43 thread descriptor used by libpthread. */ 44 dtv_t *dtv; 45 void *self; /* Pointer to the thread descriptor. */ 46 int multiple_threads; 47 } tcbhead_t; 48 49 #else /* __ASSEMBLER__ */ 50 # include <tcb-offsets.h> 51 #endif 52 53 54 #ifdef HAVE_TLS_SUPPORT 55 56 /* Signal that TLS support is available. */ 57 # define USE_TLS 1 58 59 # ifndef __ASSEMBLER__ 60 /* Get system call information. */ 61 # include <sysdep.h> 62 63 /* Get the thread descriptor definition. */ 64 # include <linuxthreads/descr.h> 65 66 /* This is the size of the initial TCB. */ 67 # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) 68 69 /* Alignment requirements for the initial TCB. */ 70 # define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) 71 72 /* This is the size of the TCB. */ 73 # define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct) 74 75 /* Alignment requirements for the TCB. */ 76 # define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) 77 78 /* The TCB can have any size and the memory following the address the 79 thread pointer points to is unspecified. Allocate the TCB there. */ 80 # define TLS_TCB_AT_TP 1 81 82 83 /* Install the dtv pointer. The pointer passed is to the element with 84 index -1 which contain the length. */ 85 # define INSTALL_DTV(descr, dtvp) \ 86 ((tcbhead_t *) (descr))->dtv = (dtvp) + 1 87 88 /* Install new dtv for current thread. */ 89 # define INSTALL_NEW_DTV(dtv) \ 90 ({ struct _pthread_descr_struct *__descr; \ 91 THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); }) 92 93 /* Return dtv of given thread descriptor. */ 94 # define GET_DTV(descr) \ 95 (((tcbhead_t *) (descr))->dtv) 96 97 /* Code to initially initialize the thread pointer. This might need 98 special attention since 'errno' is not yet available and if the 99 operation can cause a failure 'errno' must not be touched. */ 100 # define TLS_INIT_TP(descr, secondcall) \ 101 ({ \ 102 void *_descr = (descr); \ 103 tcbhead_t *head = _descr; \ 104 long int _result; \ 105 \ 106 head->tcb = _descr; \ 107 /* For now the thread descriptor is at the same address. */ \ 108 head->self = _descr; \ 109 \ 110 __asm__ __volatile__ ("syscall" \ 111 : "=a" (_result) \ 112 : "0" ((unsigned long int) __NR_arch_prctl), \ 113 "D" ((unsigned long int) ARCH_SET_FS), \ 114 "S" (_descr) \ 115 : "memory", "cc", "r11", "cx"); \ 116 \ 117 _result ? "cannot set %fs base address for thread-local storage" : 0; \ 118 }) 119 120 /* Indicate that dynamic linker shouldn't try to initialize TLS even 121 when no PT_TLS segments are found in the program and libraries 122 it is linked against. */ 123 # define TLS_INIT_TP_EXPENSIVE 1 124 125 /* Return the address of the dtv for the current thread. */ 126 # define THREAD_DTV() \ 127 ({ struct _pthread_descr_struct *__descr; \ 128 THREAD_GETMEM (__descr, p_header.data.dtvp); }) 129 130 # endif /* HAVE_TLS_SUPPORT */ 131 #endif /* __ASSEMBLER__ */ 132 133 #endif /* tls.h */ 134