diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/dl-tls.c | 25 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 5 | ||||
-rw-r--r-- | sysdeps/i386/dl-tls.h | 8 |
3 files changed, 32 insertions, 6 deletions
diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 729adf0040..1b16bd58f4 100644 --- a/sysdeps/generic/dl-tls.c +++ b/sysdeps/generic/dl-tls.c @@ -103,7 +103,21 @@ _dl_determine_tlsoffset (struct link_map *firstp) /* The thread descriptor (pointed to by the thread pointer) has its own alignment requirement. Adjust the static TLS size - appropriately. */ + and TLS offsets appropriately. */ + if (offset % TLS_TCB_ALIGN != 0) + { + size_t add = TLS_TCB_ALIGN - offset % TLS_TCB_ALIGN; + + /* XXX If the offset stored is negative we must subtract here. */ + offset += add; + + runp = firstp; + do + runp->l_tls_offset += add; + while ((runp = runp->l_tls_nextimage) != firstp); + } + + GL(dl_tls_static_size) = offset + TLS_TCB_SIZE; # elif TLS_DTV_AT_TP struct link_map *lastp; @@ -121,10 +135,17 @@ _dl_determine_tlsoffset (struct link_map *firstp) offset = roundup (offset + lastp->l_tls_blocksize, runp->l_tls_align); runp->l_tls_offset = offset; + + lastp = runp; } + + GL(dl_tls_static_size) = offset + lastp->l_tls_blocksize; # else # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # endif + + /* The alignment requirement for the static TLS block. */ + GL(dl_tls_static_align) = MAX (TLS_TCB_ALIGN, max_align); } @@ -136,7 +157,7 @@ _dl_determine_tlsoffset (struct link_map *firstp) it. Users of the IA-64 form have to provide adequate definitions of the following macros. */ # ifndef GET_ADDR_ARGS -# define GET_ADDR_ARGS struct tls_index *ti +# define GET_ADDR_ARGS tls_index *ti # endif # ifndef GET_ADDR_MODULE # define GET_ADDR_MODULE ti->ti_module diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 9913820b03..f049878cbd 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -298,6 +298,11 @@ struct rtld_global EXTERN size_t _dl_tls_max_dtv_idx; /* Flag signalling whether there are gaps in the module ID allocation. */ EXTERN bool _dl_tls_dtv_gaps; + + /* Size of the static TLS block. */ + EXTERN size_t _dl_tls_static_size; + /* Alignment requirement of the static TLS block. */ + EXTERN size_t _dl_tls_static_align; #endif /* Name of the shared object to be profiled (if any). */ diff --git a/sysdeps/i386/dl-tls.h b/sysdeps/i386/dl-tls.h index 5398609748..7fe4be8e62 100644 --- a/sysdeps/i386/dl-tls.h +++ b/sysdeps/i386/dl-tls.h @@ -19,15 +19,15 @@ #ifdef USE_TLS /* Type used for the representation of TLS information in the GOT. */ -struct tls_index +typedef struct { unsigned long int ti_module; unsigned long int ti_offset; -}; +} tls_index; /* This is the prototype for the GNU version. */ -extern void *___tls_get_addr (struct tls_index *ti) +extern void *___tls_get_addr (tls_index *ti) __attribute__ ((__regparm__ (1))); /* The special thing about the x86 TLS ABI is that we have two @@ -37,7 +37,7 @@ extern void *___tls_get_addr (struct tls_index *ti) an additional underscore at the beginning. The Sun version uses the normal calling convention. */ void * -__tls_get_addr (struct tls_index *ti) +__tls_get_addr (tls_index *ti) { return ___tls_get_addr (ti); } |