summaryrefslogtreecommitdiff
path: root/elf/dl-tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-tls.c')
-rw-r--r--elf/dl-tls.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 9454d06d72..5204fdaac0 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -105,6 +105,33 @@ _dl_next_tls_modid (void)
}
+size_t
+internal_function
+_dl_count_modids (void)
+{
+ /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
+ we fail to load a module and unload it leaving a gap. If we don't
+ have gaps then the number of modids is the current maximum so
+ return that. */
+ if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
+ return GL(dl_tls_max_dtv_idx);
+
+ /* We have gaps and are forced to count the non-NULL entries. */
+ size_t n = 0;
+ struct dtv_slotinfo_list *runp = GL(dl_tls_dtv_slotinfo_list);
+ while (runp != NULL)
+ {
+ for (size_t i = 0; i < runp->len; ++i)
+ if (runp->slotinfo[i].map != NULL)
+ ++n;
+
+ runp = runp->next;
+ }
+
+ return n;
+}
+
+
#ifdef SHARED
void
internal_function
@@ -407,6 +434,7 @@ _dl_allocate_tls_init (void *result)
/* Keep track of the maximum generation number. This might
not be the generation counter. */
+ assert (listp->slotinfo[cnt].gen <= GL(dl_tls_generation));
maxgen = MAX (maxgen, listp->slotinfo[cnt].gen);
if (map->l_tls_offset == NO_TLS_OFFSET