Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 27 Apr 2003 06:20:14 +0000 (06:20 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 27 Apr 2003 06:20:14 +0000 (06:20 +0000)
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.

ChangeLog
elf/Makefile
elf/dl-close.c
elf/dl-reloc.c
elf/tst-tls8.c
elf/tst-tlsmod13.c [new file with mode: 0644]
elf/tst-tlsmod13a.c [new file with mode: 0644]

index 2d2ebb8..9c9c227 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+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.
index 3838a11..c557bd8 100644 (file)
@@ -145,7 +145,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
         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
@@ -168,6 +168,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
                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 \
@@ -383,6 +384,7 @@ $(objpfx)tst-tlsmod3.so: $(objpfx)tst-tlsmod2.so
 $(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
@@ -590,6 +592,9 @@ $(objpfx)tst-tls11: $(objpfx)tst-tlsmod10.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
index 78b143f..b482e89 100644 (file)
@@ -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
index c7f1f34..6165fe4 100644 (file)
@@ -45,7 +45,9 @@ void
 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,
index e300bc5..97b4a25 100644 (file)
@@ -19,8 +19,8 @@ do_test (void)
   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)
@@ -35,7 +35,7 @@ do_test (void)
       /* 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)
        {
@@ -65,7 +65,7 @@ do_test (void)
       /* 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)
        {
diff --git a/elf/tst-tlsmod13.c b/elf/tst-tlsmod13.c
new file mode 100644 (file)
index 0000000..beca89f
--- /dev/null
@@ -0,0 +1,14 @@
+#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];
+}
diff --git a/elf/tst-tlsmod13a.c b/elf/tst-tlsmod13a.c
new file mode 100644 (file)
index 0000000..14b12b0
--- /dev/null
@@ -0,0 +1,16 @@
+#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];
+}