+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.
+
2003-04-26 Roland McGrath <roland@redhat.com>
* Makerules ($(common-objpfx)shlib.lds): New target.
neededtest3 neededtest4 unload2 lateglobal initfirst global \
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
- tst-tls10 tst-tls11 tst-tls12
+ tst-tls10 tst-tls11 tst-tls12 tst-tls13
# reldep9
test-srcs = tst-pathopt
tests-vis-yes = vismain
tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \
tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \
tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \
+ tst-tlsmod13 tst-tlsmod13a \
circlemod1 circlemod1a circlemod2 circlemod2a \
circlemod3 circlemod3a \
reldep8mod1 reldep8mod2 reldep8mod3 \
$(objpfx)tst-tlsmod8.so: $(objpfx)tst-tlsmod7.so
$(objpfx)tst-tlsmod10.so: $(objpfx)tst-tlsmod9.so
$(objpfx)tst-tlsmod12.so: $(objpfx)tst-tlsmod11.so
+$(objpfx)tst-tlsmod13a.so: $(objpfx)tst-tlsmod13.so
# For tst-tls9-static, make sure the modules it dlopens have libc.so in DT_NEEDED
$(objpfx)tst-tlsmod5.so: $(common-objpfx)libc.so
$(objpfx)tst-tlsmod6.so: $(common-objpfx)libc.so
$(objpfx)tst-tls12: $(objpfx)tst-tlsmod12.so
+$(objpfx)tst-tls13: $(libdl)
+$(objpfx)tst-tls13.out: $(objpfx)tst-tlsmod13a.so
+
ifdef libdl
$(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
$(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
_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
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. */
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
internal_function __attribute_noinline__
_dl_allocate_static_tls (struct link_map *map)
{
- size_t offset, used, check;
+ size_t offset;
+ size_t used;
+ size_t check;
# if TLS_TCB_AT_TP
offset = roundup (GL(dl_tls_static_used) + map->l_tls_blocksize,
void *h1;
void *h2;
int i;
- int modid1 = -1;
- int modid2 = -1;
+ size_t modid1 = (size_t) -1;
+ size_t modid2 = (size_t) -1;
int *bazp;
for (i = 0; i < 10; ++i)
/* Dirty test code here: we peek into a private data structure.
We make sure that the module gets assigned the same ID every
time. The value of the first round is used. */
- if (modid1 == -1)
+ if (modid1 == (size_t) -1)
modid1 = ((struct link_map *) h1)->l_tls_modid;
else if (((struct link_map *) h1)->l_tls_modid != modid1)
{
/* Dirty test code here: we peek into a private data structure.
We make sure that the module gets assigned the same ID every
time. The value of the first round is used. */
- if (modid2 == -1)
+ if (modid2 == (size_t) -1)
modid2 = ((struct link_map *) h1)->l_tls_modid;
else if (((struct link_map *) h1)->l_tls_modid != modid2)
{
--- /dev/null
+#include <tls.h>
+
+#if defined USE_TLS && defined HAVE___THREAD \
+ && defined HAVE_TLS_MODEL_ATTRIBUTE
+__thread int a[2] __attribute__ ((tls_model ("initial-exec")));
+#else
+int a[2];
+#endif
+
+int
+foo (void)
+{
+ return a[0];
+}
--- /dev/null
+#include <tls.h>
+
+#if defined USE_TLS && defined HAVE___THREAD \
+ && defined HAVE_TLS_MODEL_ATTRIBUTE
+__thread int b[2] __attribute__ ((tls_model ("initial-exec")));
+#else
+int b[2];
+#endif
+
+extern int foo (void);
+
+int
+bar (void)
+{
+ return foo () + b[0];
+}