aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-close.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-27 06:20:14 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-27 06:20:14 +0000
commit541765b6b478c98825eb35759ed558489448771f (patch)
tree0121a45ee77606a395dce5719ef14f65d57fb459 /elf/dl-close.c
parent669863e27194ac7ddeffa2843d96949a1e082ece (diff)
downloadglibc-541765b6b478c98825eb35759ed558489448771f.tar
glibc-541765b6b478c98825eb35759ed558489448771f.tar.gz
glibc-541765b6b478c98825eb35759ed558489448771f.tar.bz2
glibc-541765b6b478c98825eb35759ed558489448771f.zip
Update.
2003-04-26 Ulrich Drepper <drepper@redhat.com> * elf/dl-close.c [USE_TLS && TLS_TCB_AT_TP] (_dl_close): Reimplement tracking of freed memory in static TLS block. * elf/Makefile: Add rules to build and run tst-tls13. * elf/tst-tls13.c: New file. * elf/tst-tlsmod13.c: New file. * elf/tst-tlsmod13a.c: New file. * elf/tst-tls8.c: Adjust types of variables to avoid warnings. * elf/dl-reloc.c: Pretty printing.
Diffstat (limited to 'elf/dl-close.c')
-rw-r--r--elf/dl-close.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 78b143f8ec..b482e89f13 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -321,8 +321,9 @@ _dl_close (void *_map)
_dl_debug_state ();
#ifdef USE_TLS
- size_t tls_free_start, tls_free_end;
- tls_free_start = tls_free_end = GL(dl_tls_static_used);
+ size_t tls_free_start;
+ size_t tls_free_end;
+ tls_free_start = tls_free_end = NO_TLS_OFFSET;
#endif
/* Check each element of the search list to see if all references to
@@ -371,9 +372,50 @@ _dl_close (void *_map)
this search list, going in either direction. When the
whole chunk is at the end of the used area then we can
reclaim it. */
+# if TLS_TCB_AT_TP
+ if (tls_free_start == NO_TLS_OFFSET
+ || (size_t) imap->l_tls_offset == tls_free_start)
+ {
+ /* Extend the contiguous chunk being reclaimed. */
+ tls_free_start
+ = imap->l_tls_offset - imap->l_tls_blocksize;
+
+ if (tls_free_end == NO_TLS_OFFSET)
+ tls_free_end = imap->l_tls_offset;
+ }
+ else if (imap->l_tls_offset - imap->l_tls_blocksize
+ == tls_free_end)
+ /* Extend the chunk backwards. */
+ tls_free_end = imap->l_tls_offset;
+ else
+ {
+ /* This isn't contiguous with the last chunk freed.
+ One of them will be leaked unless we can free
+ one block right away. */
+ if (tls_free_end == GL(dl_tls_static_used))
+ {
+ GL(dl_tls_static_used) = tls_free_start;
+ tls_free_end = imap->l_tls_offset;
+ tls_free_start
+ = tls_free_end - imap->l_tls_blocksize;
+ }
+ else if ((size_t) imap->l_tls_offset
+ == GL(dl_tls_static_used))
+ GL(dl_tls_static_used)
+ = imap->l_tls_offset - imap->l_tls_blocksize;
+ else if (tls_free_end < (size_t) imap->l_tls_offset)
+ {
+ /* We pick the later block. It has a chance to
+ be freed. */
+ tls_free_end = imap->l_tls_offset;
+ tls_free_start
+ = tls_free_end - imap->l_tls_blocksize;
+ }
+ }
+# elif TLS_DTV_AT_TP
if ((size_t) imap->l_tls_offset == tls_free_end)
/* Extend the contiguous chunk being reclaimed. */
- tls_free_end += imap->l_tls_blocksize;
+ tls_free_end -= imap->l_tls_blocksize;
else if (imap->l_tls_offset + imap->l_tls_blocksize
== tls_free_start)
/* Extend the chunk backwards. */
@@ -387,6 +429,9 @@ _dl_close (void *_map)
tls_free_start = imap->l_tls_offset;
tls_free_end = tls_free_start + imap->l_tls_blocksize;
}
+# else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+# endif
}
}
#endif