aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/dl-tls.c25
-rw-r--r--sysdeps/generic/ldsodefs.h5
-rw-r--r--sysdeps/i386/dl-tls.h8
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);
}